瀏覽代碼

Add basic support for playlists

HEnquist 5 年之前
父節點
當前提交
5b26529811

+ 88 - 0
examples/playlist_tracks.rs

@@ -0,0 +1,88 @@
+#[macro_use]
+extern crate log;
+extern crate env_logger;
+
+extern crate librespot;
+extern crate tokio_core;
+//extern crate tokio_fs;
+extern crate tokio_io;
+extern crate futures;
+//extern crate futures_cpupool;
+
+use std::env;
+use tokio_core::reactor::Core;
+
+use librespot::core::authentication::Credentials;
+use librespot::core::config::SessionConfig;
+use librespot::core::session::Session;
+use librespot::core::spotify_id::SpotifyId;
+use librespot::playback::config::PlayerConfig;
+use librespot::playback::config::Bitrate;
+use librespot::metadata::{FileFormat, Metadata, PlaylistMeta, Track, Album, Artist, Playlist};
+
+
+/*
+fn make_list_playlist(core: &mut Core, session: &Session, uri: &str) -> TrackList {
+    let mut tracks = Vec::new();
+    let mut fnames = Vec::new();
+
+    let plist_uri = SpotifyId::from_base62(&uri).unwrap();
+    let plist = core.run(Playlist::get(&session, plist_uri)).unwrap();
+    println!("album name: {}",plist.name);
+    let plist_name = &plist.name;
+
+    
+
+    for (i, track_id) in plist.tracks.iter().enumerate() {
+        let plist_track = core.run(Track::get(&session, *track_id)).unwrap();
+        //println!("album track: {} - {}",i+1, alb_track.name);
+        let artist = core.run(Artist::get(&session, plist_track.artists[0])).unwrap();
+        println!("track artist: {}",artist.name);
+        tracks.push(plist_track.id);
+        let filename = format!("{} - {}.ogg",&artist.name, alb_track.name);
+        fnames.push(filename);
+    }
+    let ntr = plist.tracks.len();
+
+    let folder = format!("{}",plist_name);
+    let mut tlist = TrackList::new(ntr, folder, tracks, fnames);
+    tlist
+}
+*/
+
+fn main() {
+    env_logger::init();
+    let mut core = Core::new().unwrap();
+    let handle = core.handle();
+
+    let session_config = SessionConfig::default();
+    let mut player_config = PlayerConfig::default();
+    player_config.bitrate = Bitrate::Bitrate320;
+
+    let args: Vec<_> = env::args().collect();
+    if args.len() != 5 {
+        println!("Usage: {} USERNAME PASSWORD PLAYLIST PLISTUSER", args[0]);
+    }
+    let username = args[1].to_owned();
+    let password = args[2].to_owned();
+    let credentials = Credentials::with_password(username, password);
+
+    let plist_owner = args[4].to_string();
+
+    let mut uri_split = args[3].split(":");
+    let uri_parts: Vec<&str> = uri_split.collect();
+    println!("{}, {}, {}",uri_parts[0], uri_parts[1], uri_parts[2]);
+    
+    let plist_uri = SpotifyId::from_base62(uri_parts[2]).unwrap();
+    
+    let session = core
+        .run(Session::connect(session_config, credentials, None, handle))
+        .unwrap();
+
+    let plist = core.run(Playlist::get(&session, plist_uri, plist_owner, 0, 100)).unwrap();
+    println!("{:?}",plist);
+    for track_id in plist.tracks {
+        let plist_track = core.run(Track::get(&session, track_id)).unwrap();
+        println!("track: {} ", plist_track.name);
+    }
+}

+ 62 - 0
metadata/src/lib.rs

@@ -141,6 +141,29 @@ pub trait Metadata: Send + Sized + 'static {
     }
 }
 
+pub trait PlaylistMeta: Send + Sized + 'static {
+    type Message: protobuf::Message;
+
+    fn base_url() -> &'static str;
+    fn parse(msg: &Self::Message, session: &Session) -> Self;
+
+    fn get(session: &Session, id: SpotifyId, user: String, start: i32, len: i32) -> Box<Future<Item = Self, Error = MercuryError>> {
+        //let uri = format!("hm://playlist/{}?from={}&length={}",id.to_base62(), 0, 100);
+        let uri = format!("hm://playlist/user/{}/playlist/{}?from={}&length={}", user, id.to_base62(), start, len);
+        println!("request uri: {}", uri);
+        let request = session.mercury().get(uri);
+        println!("a");
+        let session = session.clone();
+        Box::new(request.and_then(move |response| {
+            println!("{:?}", response);
+            let data = response.payload.first().expect("Empty payload");
+            let msg: Self::Message = protobuf::parse_from_bytes(data).unwrap();
+            println!("{:?}", msg);
+            Ok(Self::parse(&msg, &session))
+        }))
+    }
+}
+
 #[derive(Debug, Clone)]
 pub struct Track {
     pub id: SpotifyId,
@@ -185,6 +208,14 @@ pub struct Show {
     pub covers: Vec<FileId>,
 }
 
+#[derive(Debug, Clone)]
+pub struct Playlist {
+    //pub id: SpotifyId,
+    pub length: i32,
+    pub name: String,
+    pub tracks: Vec<SpotifyId>,
+}
+
 #[derive(Debug, Clone)]
 pub struct Artist {
     pub id: SpotifyId,
@@ -282,6 +313,37 @@ impl Metadata for Album {
     }
 }
 
+impl PlaylistMeta for Playlist {
+    type Message = protocol::playlist4changes::SelectedListContent;
+
+    fn base_url() -> &'static str {
+        "hm://playlist/'?from=' + from + '&length=' + length"
+    }
+
+
+    fn parse(msg: &Self::Message, _: &Session) -> Self {
+
+        let tracks = msg
+            .get_contents()
+            .get_items()
+            .iter()
+            .map(|item| {
+                let uri_split = item.get_uri().split(":");
+                let uri_parts: Vec<&str> = uri_split.collect();
+                SpotifyId::from_base62(uri_parts[2]).unwrap()
+            })
+            .collect::<Vec<_>>();
+        
+        println!("parse Message: {:?}", msg);
+        Playlist {
+            //id: SpotifyId::from_raw(msg.get_attributes().get_id()).unwrap(),
+            name: msg.get_attributes().get_name().to_owned(),
+            length: msg.get_length(),
+            tracks: tracks,
+        }
+    }
+}
+
 impl Metadata for Artist {
     type Message = protocol::metadata::Artist;
 

+ 5 - 0
protocol/src/lib.rs

@@ -5,5 +5,10 @@ pub mod authentication;
 pub mod keyexchange;
 pub mod mercury;
 pub mod metadata;
+pub mod playlist4changes;
+pub mod playlist4content;
+pub mod playlist4issues;
+pub mod playlist4meta;
+pub mod playlist4ops;
 pub mod pubsub;
 pub mod spirc;

+ 3565 - 0
protocol/src/playlist4changes.rs

@@ -0,0 +1,3565 @@
+// This file is generated by rust-protobuf 2.7.0. Do not edit
+// @generated
+
+// https://github.com/Manishearth/rust-clippy/issues/702
+#![allow(unknown_lints)]
+#![allow(clippy::all)]
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+
+#![allow(box_pointers)]
+#![allow(dead_code)]
+#![allow(missing_docs)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![allow(trivial_casts)]
+#![allow(unsafe_code)]
+#![allow(unused_imports)]
+#![allow(unused_results)]
+//! Generated file from `playlist4changes.proto`
+
+use protobuf::Message as Message_imported_for_functions;
+use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
+
+/// Generated files are compatible only with the same version
+/// of protobuf runtime.
+const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_7_0;
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ChangeInfo {
+    // message fields
+    user: ::protobuf::SingularField<::std::string::String>,
+    timestamp: ::std::option::Option<i32>,
+    admin: ::std::option::Option<bool>,
+    undo: ::std::option::Option<bool>,
+    redo: ::std::option::Option<bool>,
+    merge: ::std::option::Option<bool>,
+    compressed: ::std::option::Option<bool>,
+    migration: ::std::option::Option<bool>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ChangeInfo {
+    fn default() -> &'a ChangeInfo {
+        <ChangeInfo as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ChangeInfo {
+    pub fn new() -> ChangeInfo {
+        ::std::default::Default::default()
+    }
+
+    // optional string user = 1;
+
+
+    pub fn get_user(&self) -> &str {
+        match self.user.as_ref() {
+            Some(v) => &v,
+            None => "",
+        }
+    }
+    pub fn clear_user(&mut self) {
+        self.user.clear();
+    }
+
+    pub fn has_user(&self) -> bool {
+        self.user.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_user(&mut self, v: ::std::string::String) {
+        self.user = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_user(&mut self) -> &mut ::std::string::String {
+        if self.user.is_none() {
+            self.user.set_default();
+        }
+        self.user.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_user(&mut self) -> ::std::string::String {
+        self.user.take().unwrap_or_else(|| ::std::string::String::new())
+    }
+
+    // optional int32 timestamp = 2;
+
+
+    pub fn get_timestamp(&self) -> i32 {
+        self.timestamp.unwrap_or(0)
+    }
+    pub fn clear_timestamp(&mut self) {
+        self.timestamp = ::std::option::Option::None;
+    }
+
+    pub fn has_timestamp(&self) -> bool {
+        self.timestamp.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_timestamp(&mut self, v: i32) {
+        self.timestamp = ::std::option::Option::Some(v);
+    }
+
+    // optional bool admin = 3;
+
+
+    pub fn get_admin(&self) -> bool {
+        self.admin.unwrap_or(false)
+    }
+    pub fn clear_admin(&mut self) {
+        self.admin = ::std::option::Option::None;
+    }
+
+    pub fn has_admin(&self) -> bool {
+        self.admin.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_admin(&mut self, v: bool) {
+        self.admin = ::std::option::Option::Some(v);
+    }
+
+    // optional bool undo = 4;
+
+
+    pub fn get_undo(&self) -> bool {
+        self.undo.unwrap_or(false)
+    }
+    pub fn clear_undo(&mut self) {
+        self.undo = ::std::option::Option::None;
+    }
+
+    pub fn has_undo(&self) -> bool {
+        self.undo.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_undo(&mut self, v: bool) {
+        self.undo = ::std::option::Option::Some(v);
+    }
+
+    // optional bool redo = 5;
+
+
+    pub fn get_redo(&self) -> bool {
+        self.redo.unwrap_or(false)
+    }
+    pub fn clear_redo(&mut self) {
+        self.redo = ::std::option::Option::None;
+    }
+
+    pub fn has_redo(&self) -> bool {
+        self.redo.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_redo(&mut self, v: bool) {
+        self.redo = ::std::option::Option::Some(v);
+    }
+
+    // optional bool merge = 6;
+
+
+    pub fn get_merge(&self) -> bool {
+        self.merge.unwrap_or(false)
+    }
+    pub fn clear_merge(&mut self) {
+        self.merge = ::std::option::Option::None;
+    }
+
+    pub fn has_merge(&self) -> bool {
+        self.merge.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_merge(&mut self, v: bool) {
+        self.merge = ::std::option::Option::Some(v);
+    }
+
+    // optional bool compressed = 7;
+
+
+    pub fn get_compressed(&self) -> bool {
+        self.compressed.unwrap_or(false)
+    }
+    pub fn clear_compressed(&mut self) {
+        self.compressed = ::std::option::Option::None;
+    }
+
+    pub fn has_compressed(&self) -> bool {
+        self.compressed.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_compressed(&mut self, v: bool) {
+        self.compressed = ::std::option::Option::Some(v);
+    }
+
+    // optional bool migration = 8;
+
+
+    pub fn get_migration(&self) -> bool {
+        self.migration.unwrap_or(false)
+    }
+    pub fn clear_migration(&mut self) {
+        self.migration = ::std::option::Option::None;
+    }
+
+    pub fn has_migration(&self) -> bool {
+        self.migration.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_migration(&mut self, v: bool) {
+        self.migration = ::std::option::Option::Some(v);
+    }
+}
+
+impl ::protobuf::Message for ChangeInfo {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.user)?;
+                },
+                2 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.timestamp = ::std::option::Option::Some(tmp);
+                },
+                3 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.admin = ::std::option::Option::Some(tmp);
+                },
+                4 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.undo = ::std::option::Option::Some(tmp);
+                },
+                5 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.redo = ::std::option::Option::Some(tmp);
+                },
+                6 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.merge = ::std::option::Option::Some(tmp);
+                },
+                7 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.compressed = ::std::option::Option::Some(tmp);
+                },
+                8 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.migration = ::std::option::Option::Some(tmp);
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.user.as_ref() {
+            my_size += ::protobuf::rt::string_size(1, &v);
+        }
+        if let Some(v) = self.timestamp {
+            my_size += ::protobuf::rt::value_size(2, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(v) = self.admin {
+            my_size += 2;
+        }
+        if let Some(v) = self.undo {
+            my_size += 2;
+        }
+        if let Some(v) = self.redo {
+            my_size += 2;
+        }
+        if let Some(v) = self.merge {
+            my_size += 2;
+        }
+        if let Some(v) = self.compressed {
+            my_size += 2;
+        }
+        if let Some(v) = self.migration {
+            my_size += 2;
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.user.as_ref() {
+            os.write_string(1, &v)?;
+        }
+        if let Some(v) = self.timestamp {
+            os.write_int32(2, v)?;
+        }
+        if let Some(v) = self.admin {
+            os.write_bool(3, v)?;
+        }
+        if let Some(v) = self.undo {
+            os.write_bool(4, v)?;
+        }
+        if let Some(v) = self.redo {
+            os.write_bool(5, v)?;
+        }
+        if let Some(v) = self.merge {
+            os.write_bool(6, v)?;
+        }
+        if let Some(v) = self.compressed {
+            os.write_bool(7, v)?;
+        }
+        if let Some(v) = self.migration {
+            os.write_bool(8, v)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ChangeInfo {
+        ChangeInfo::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                    "user",
+                    |m: &ChangeInfo| { &m.user },
+                    |m: &mut ChangeInfo| { &mut m.user },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "timestamp",
+                    |m: &ChangeInfo| { &m.timestamp },
+                    |m: &mut ChangeInfo| { &mut m.timestamp },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "admin",
+                    |m: &ChangeInfo| { &m.admin },
+                    |m: &mut ChangeInfo| { &mut m.admin },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "undo",
+                    |m: &ChangeInfo| { &m.undo },
+                    |m: &mut ChangeInfo| { &mut m.undo },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "redo",
+                    |m: &ChangeInfo| { &m.redo },
+                    |m: &mut ChangeInfo| { &mut m.redo },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "merge",
+                    |m: &ChangeInfo| { &m.merge },
+                    |m: &mut ChangeInfo| { &mut m.merge },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "compressed",
+                    |m: &ChangeInfo| { &m.compressed },
+                    |m: &mut ChangeInfo| { &mut m.compressed },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "migration",
+                    |m: &ChangeInfo| { &m.migration },
+                    |m: &mut ChangeInfo| { &mut m.migration },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<ChangeInfo>(
+                    "ChangeInfo",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static ChangeInfo {
+        static mut instance: ::protobuf::lazy::Lazy<ChangeInfo> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ChangeInfo,
+        };
+        unsafe {
+            instance.get(ChangeInfo::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for ChangeInfo {
+    fn clear(&mut self) {
+        self.user.clear();
+        self.timestamp = ::std::option::Option::None;
+        self.admin = ::std::option::Option::None;
+        self.undo = ::std::option::Option::None;
+        self.redo = ::std::option::Option::None;
+        self.merge = ::std::option::Option::None;
+        self.compressed = ::std::option::Option::None;
+        self.migration = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ChangeInfo {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ChangeInfo {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct Delta {
+    // message fields
+    base_version: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+    ops: ::protobuf::RepeatedField<super::playlist4ops::Op>,
+    info: ::protobuf::SingularPtrField<ChangeInfo>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a Delta {
+    fn default() -> &'a Delta {
+        <Delta as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl Delta {
+    pub fn new() -> Delta {
+        ::std::default::Default::default()
+    }
+
+    // optional bytes base_version = 1;
+
+
+    pub fn get_base_version(&self) -> &[u8] {
+        match self.base_version.as_ref() {
+            Some(v) => &v,
+            None => &[],
+        }
+    }
+    pub fn clear_base_version(&mut self) {
+        self.base_version.clear();
+    }
+
+    pub fn has_base_version(&self) -> bool {
+        self.base_version.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_base_version(&mut self, v: ::std::vec::Vec<u8>) {
+        self.base_version = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_base_version(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.base_version.is_none() {
+            self.base_version.set_default();
+        }
+        self.base_version.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_base_version(&mut self) -> ::std::vec::Vec<u8> {
+        self.base_version.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    }
+
+    // repeated .Op ops = 2;
+
+
+    pub fn get_ops(&self) -> &[super::playlist4ops::Op] {
+        &self.ops
+    }
+    pub fn clear_ops(&mut self) {
+        self.ops.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_ops(&mut self, v: ::protobuf::RepeatedField<super::playlist4ops::Op>) {
+        self.ops = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_ops(&mut self) -> &mut ::protobuf::RepeatedField<super::playlist4ops::Op> {
+        &mut self.ops
+    }
+
+    // Take field
+    pub fn take_ops(&mut self) -> ::protobuf::RepeatedField<super::playlist4ops::Op> {
+        ::std::mem::replace(&mut self.ops, ::protobuf::RepeatedField::new())
+    }
+
+    // optional .ChangeInfo info = 4;
+
+
+    pub fn get_info(&self) -> &ChangeInfo {
+        self.info.as_ref().unwrap_or_else(|| ChangeInfo::default_instance())
+    }
+    pub fn clear_info(&mut self) {
+        self.info.clear();
+    }
+
+    pub fn has_info(&self) -> bool {
+        self.info.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_info(&mut self, v: ChangeInfo) {
+        self.info = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_info(&mut self) -> &mut ChangeInfo {
+        if self.info.is_none() {
+            self.info.set_default();
+        }
+        self.info.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_info(&mut self) -> ChangeInfo {
+        self.info.take().unwrap_or_else(|| ChangeInfo::new())
+    }
+}
+
+impl ::protobuf::Message for Delta {
+    fn is_initialized(&self) -> bool {
+        for v in &self.ops {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.info {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.base_version)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.ops)?;
+                },
+                4 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.info)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.base_version.as_ref() {
+            my_size += ::protobuf::rt::bytes_size(1, &v);
+        }
+        for value in &self.ops {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        if let Some(ref v) = self.info.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.base_version.as_ref() {
+            os.write_bytes(1, &v)?;
+        }
+        for v in &self.ops {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        if let Some(ref v) = self.info.as_ref() {
+            os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> Delta {
+        Delta::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                    "base_version",
+                    |m: &Delta| { &m.base_version },
+                    |m: &mut Delta| { &mut m.base_version },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4ops::Op>>(
+                    "ops",
+                    |m: &Delta| { &m.ops },
+                    |m: &mut Delta| { &mut m.ops },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ChangeInfo>>(
+                    "info",
+                    |m: &Delta| { &m.info },
+                    |m: &mut Delta| { &mut m.info },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<Delta>(
+                    "Delta",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static Delta {
+        static mut instance: ::protobuf::lazy::Lazy<Delta> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const Delta,
+        };
+        unsafe {
+            instance.get(Delta::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for Delta {
+    fn clear(&mut self) {
+        self.base_version.clear();
+        self.ops.clear();
+        self.info.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for Delta {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for Delta {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct Merge {
+    // message fields
+    base_version: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+    merge_version: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+    info: ::protobuf::SingularPtrField<ChangeInfo>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a Merge {
+    fn default() -> &'a Merge {
+        <Merge as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl Merge {
+    pub fn new() -> Merge {
+        ::std::default::Default::default()
+    }
+
+    // optional bytes base_version = 1;
+
+
+    pub fn get_base_version(&self) -> &[u8] {
+        match self.base_version.as_ref() {
+            Some(v) => &v,
+            None => &[],
+        }
+    }
+    pub fn clear_base_version(&mut self) {
+        self.base_version.clear();
+    }
+
+    pub fn has_base_version(&self) -> bool {
+        self.base_version.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_base_version(&mut self, v: ::std::vec::Vec<u8>) {
+        self.base_version = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_base_version(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.base_version.is_none() {
+            self.base_version.set_default();
+        }
+        self.base_version.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_base_version(&mut self) -> ::std::vec::Vec<u8> {
+        self.base_version.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    }
+
+    // optional bytes merge_version = 2;
+
+
+    pub fn get_merge_version(&self) -> &[u8] {
+        match self.merge_version.as_ref() {
+            Some(v) => &v,
+            None => &[],
+        }
+    }
+    pub fn clear_merge_version(&mut self) {
+        self.merge_version.clear();
+    }
+
+    pub fn has_merge_version(&self) -> bool {
+        self.merge_version.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_merge_version(&mut self, v: ::std::vec::Vec<u8>) {
+        self.merge_version = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_merge_version(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.merge_version.is_none() {
+            self.merge_version.set_default();
+        }
+        self.merge_version.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_merge_version(&mut self) -> ::std::vec::Vec<u8> {
+        self.merge_version.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    }
+
+    // optional .ChangeInfo info = 4;
+
+
+    pub fn get_info(&self) -> &ChangeInfo {
+        self.info.as_ref().unwrap_or_else(|| ChangeInfo::default_instance())
+    }
+    pub fn clear_info(&mut self) {
+        self.info.clear();
+    }
+
+    pub fn has_info(&self) -> bool {
+        self.info.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_info(&mut self, v: ChangeInfo) {
+        self.info = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_info(&mut self) -> &mut ChangeInfo {
+        if self.info.is_none() {
+            self.info.set_default();
+        }
+        self.info.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_info(&mut self) -> ChangeInfo {
+        self.info.take().unwrap_or_else(|| ChangeInfo::new())
+    }
+}
+
+impl ::protobuf::Message for Merge {
+    fn is_initialized(&self) -> bool {
+        for v in &self.info {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.base_version)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.merge_version)?;
+                },
+                4 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.info)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.base_version.as_ref() {
+            my_size += ::protobuf::rt::bytes_size(1, &v);
+        }
+        if let Some(ref v) = self.merge_version.as_ref() {
+            my_size += ::protobuf::rt::bytes_size(2, &v);
+        }
+        if let Some(ref v) = self.info.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.base_version.as_ref() {
+            os.write_bytes(1, &v)?;
+        }
+        if let Some(ref v) = self.merge_version.as_ref() {
+            os.write_bytes(2, &v)?;
+        }
+        if let Some(ref v) = self.info.as_ref() {
+            os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> Merge {
+        Merge::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                    "base_version",
+                    |m: &Merge| { &m.base_version },
+                    |m: &mut Merge| { &mut m.base_version },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                    "merge_version",
+                    |m: &Merge| { &m.merge_version },
+                    |m: &mut Merge| { &mut m.merge_version },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ChangeInfo>>(
+                    "info",
+                    |m: &Merge| { &m.info },
+                    |m: &mut Merge| { &mut m.info },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<Merge>(
+                    "Merge",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static Merge {
+        static mut instance: ::protobuf::lazy::Lazy<Merge> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const Merge,
+        };
+        unsafe {
+            instance.get(Merge::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for Merge {
+    fn clear(&mut self) {
+        self.base_version.clear();
+        self.merge_version.clear();
+        self.info.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for Merge {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for Merge {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ChangeSet {
+    // message fields
+    kind: ::std::option::Option<ChangeSet_Kind>,
+    delta: ::protobuf::SingularPtrField<Delta>,
+    merge: ::protobuf::SingularPtrField<Merge>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ChangeSet {
+    fn default() -> &'a ChangeSet {
+        <ChangeSet as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ChangeSet {
+    pub fn new() -> ChangeSet {
+        ::std::default::Default::default()
+    }
+
+    // optional .ChangeSet.Kind kind = 1;
+
+
+    pub fn get_kind(&self) -> ChangeSet_Kind {
+        self.kind.unwrap_or(ChangeSet_Kind::KIND_UNKNOWN)
+    }
+    pub fn clear_kind(&mut self) {
+        self.kind = ::std::option::Option::None;
+    }
+
+    pub fn has_kind(&self) -> bool {
+        self.kind.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_kind(&mut self, v: ChangeSet_Kind) {
+        self.kind = ::std::option::Option::Some(v);
+    }
+
+    // optional .Delta delta = 2;
+
+
+    pub fn get_delta(&self) -> &Delta {
+        self.delta.as_ref().unwrap_or_else(|| Delta::default_instance())
+    }
+    pub fn clear_delta(&mut self) {
+        self.delta.clear();
+    }
+
+    pub fn has_delta(&self) -> bool {
+        self.delta.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_delta(&mut self, v: Delta) {
+        self.delta = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_delta(&mut self) -> &mut Delta {
+        if self.delta.is_none() {
+            self.delta.set_default();
+        }
+        self.delta.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_delta(&mut self) -> Delta {
+        self.delta.take().unwrap_or_else(|| Delta::new())
+    }
+
+    // optional .Merge merge = 3;
+
+
+    pub fn get_merge(&self) -> &Merge {
+        self.merge.as_ref().unwrap_or_else(|| Merge::default_instance())
+    }
+    pub fn clear_merge(&mut self) {
+        self.merge.clear();
+    }
+
+    pub fn has_merge(&self) -> bool {
+        self.merge.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_merge(&mut self, v: Merge) {
+        self.merge = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_merge(&mut self) -> &mut Merge {
+        if self.merge.is_none() {
+            self.merge.set_default();
+        }
+        self.merge.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_merge(&mut self) -> Merge {
+        self.merge.take().unwrap_or_else(|| Merge::new())
+    }
+}
+
+impl ::protobuf::Message for ChangeSet {
+    fn is_initialized(&self) -> bool {
+        for v in &self.delta {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.merge {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_proto2_enum_with_unknown_fields_into(wire_type, is, &mut self.kind, 1, &mut self.unknown_fields)?
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.delta)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.merge)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(v) = self.kind {
+            my_size += ::protobuf::rt::enum_size(1, v);
+        }
+        if let Some(ref v) = self.delta.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.merge.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(v) = self.kind {
+            os.write_enum(1, v.value())?;
+        }
+        if let Some(ref v) = self.delta.as_ref() {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.merge.as_ref() {
+            os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ChangeSet {
+        ChangeSet::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ChangeSet_Kind>>(
+                    "kind",
+                    |m: &ChangeSet| { &m.kind },
+                    |m: &mut ChangeSet| { &mut m.kind },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Delta>>(
+                    "delta",
+                    |m: &ChangeSet| { &m.delta },
+                    |m: &mut ChangeSet| { &mut m.delta },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Merge>>(
+                    "merge",
+                    |m: &ChangeSet| { &m.merge },
+                    |m: &mut ChangeSet| { &mut m.merge },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<ChangeSet>(
+                    "ChangeSet",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static ChangeSet {
+        static mut instance: ::protobuf::lazy::Lazy<ChangeSet> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ChangeSet,
+        };
+        unsafe {
+            instance.get(ChangeSet::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for ChangeSet {
+    fn clear(&mut self) {
+        self.kind = ::std::option::Option::None;
+        self.delta.clear();
+        self.merge.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ChangeSet {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ChangeSet {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(Clone,PartialEq,Eq,Debug,Hash)]
+pub enum ChangeSet_Kind {
+    KIND_UNKNOWN = 0,
+    DELTA = 2,
+    MERGE = 3,
+}
+
+impl ::protobuf::ProtobufEnum for ChangeSet_Kind {
+    fn value(&self) -> i32 {
+        *self as i32
+    }
+
+    fn from_i32(value: i32) -> ::std::option::Option<ChangeSet_Kind> {
+        match value {
+            0 => ::std::option::Option::Some(ChangeSet_Kind::KIND_UNKNOWN),
+            2 => ::std::option::Option::Some(ChangeSet_Kind::DELTA),
+            3 => ::std::option::Option::Some(ChangeSet_Kind::MERGE),
+            _ => ::std::option::Option::None
+        }
+    }
+
+    fn values() -> &'static [Self] {
+        static values: &'static [ChangeSet_Kind] = &[
+            ChangeSet_Kind::KIND_UNKNOWN,
+            ChangeSet_Kind::DELTA,
+            ChangeSet_Kind::MERGE,
+        ];
+        values
+    }
+
+    fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::EnumDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                ::protobuf::reflect::EnumDescriptor::new("ChangeSet_Kind", file_descriptor_proto())
+            })
+        }
+    }
+}
+
+impl ::std::marker::Copy for ChangeSet_Kind {
+}
+
+impl ::std::default::Default for ChangeSet_Kind {
+    fn default() -> Self {
+        ChangeSet_Kind::KIND_UNKNOWN
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ChangeSet_Kind {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor())
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct RevisionTaggedChangeSet {
+    // message fields
+    revision: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+    change_set: ::protobuf::SingularPtrField<ChangeSet>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a RevisionTaggedChangeSet {
+    fn default() -> &'a RevisionTaggedChangeSet {
+        <RevisionTaggedChangeSet as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl RevisionTaggedChangeSet {
+    pub fn new() -> RevisionTaggedChangeSet {
+        ::std::default::Default::default()
+    }
+
+    // optional bytes revision = 1;
+
+
+    pub fn get_revision(&self) -> &[u8] {
+        match self.revision.as_ref() {
+            Some(v) => &v,
+            None => &[],
+        }
+    }
+    pub fn clear_revision(&mut self) {
+        self.revision.clear();
+    }
+
+    pub fn has_revision(&self) -> bool {
+        self.revision.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_revision(&mut self, v: ::std::vec::Vec<u8>) {
+        self.revision = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_revision(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.revision.is_none() {
+            self.revision.set_default();
+        }
+        self.revision.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_revision(&mut self) -> ::std::vec::Vec<u8> {
+        self.revision.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    }
+
+    // optional .ChangeSet change_set = 2;
+
+
+    pub fn get_change_set(&self) -> &ChangeSet {
+        self.change_set.as_ref().unwrap_or_else(|| ChangeSet::default_instance())
+    }
+    pub fn clear_change_set(&mut self) {
+        self.change_set.clear();
+    }
+
+    pub fn has_change_set(&self) -> bool {
+        self.change_set.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_change_set(&mut self, v: ChangeSet) {
+        self.change_set = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_change_set(&mut self) -> &mut ChangeSet {
+        if self.change_set.is_none() {
+            self.change_set.set_default();
+        }
+        self.change_set.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_change_set(&mut self) -> ChangeSet {
+        self.change_set.take().unwrap_or_else(|| ChangeSet::new())
+    }
+}
+
+impl ::protobuf::Message for RevisionTaggedChangeSet {
+    fn is_initialized(&self) -> bool {
+        for v in &self.change_set {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.revision)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.change_set)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.revision.as_ref() {
+            my_size += ::protobuf::rt::bytes_size(1, &v);
+        }
+        if let Some(ref v) = self.change_set.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.revision.as_ref() {
+            os.write_bytes(1, &v)?;
+        }
+        if let Some(ref v) = self.change_set.as_ref() {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> RevisionTaggedChangeSet {
+        RevisionTaggedChangeSet::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                    "revision",
+                    |m: &RevisionTaggedChangeSet| { &m.revision },
+                    |m: &mut RevisionTaggedChangeSet| { &mut m.revision },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ChangeSet>>(
+                    "change_set",
+                    |m: &RevisionTaggedChangeSet| { &m.change_set },
+                    |m: &mut RevisionTaggedChangeSet| { &mut m.change_set },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<RevisionTaggedChangeSet>(
+                    "RevisionTaggedChangeSet",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static RevisionTaggedChangeSet {
+        static mut instance: ::protobuf::lazy::Lazy<RevisionTaggedChangeSet> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const RevisionTaggedChangeSet,
+        };
+        unsafe {
+            instance.get(RevisionTaggedChangeSet::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for RevisionTaggedChangeSet {
+    fn clear(&mut self) {
+        self.revision.clear();
+        self.change_set.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for RevisionTaggedChangeSet {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for RevisionTaggedChangeSet {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct Diff {
+    // message fields
+    from_revision: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+    ops: ::protobuf::RepeatedField<super::playlist4ops::Op>,
+    to_revision: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a Diff {
+    fn default() -> &'a Diff {
+        <Diff as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl Diff {
+    pub fn new() -> Diff {
+        ::std::default::Default::default()
+    }
+
+    // optional bytes from_revision = 1;
+
+
+    pub fn get_from_revision(&self) -> &[u8] {
+        match self.from_revision.as_ref() {
+            Some(v) => &v,
+            None => &[],
+        }
+    }
+    pub fn clear_from_revision(&mut self) {
+        self.from_revision.clear();
+    }
+
+    pub fn has_from_revision(&self) -> bool {
+        self.from_revision.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_from_revision(&mut self, v: ::std::vec::Vec<u8>) {
+        self.from_revision = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_from_revision(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.from_revision.is_none() {
+            self.from_revision.set_default();
+        }
+        self.from_revision.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_from_revision(&mut self) -> ::std::vec::Vec<u8> {
+        self.from_revision.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    }
+
+    // repeated .Op ops = 2;
+
+
+    pub fn get_ops(&self) -> &[super::playlist4ops::Op] {
+        &self.ops
+    }
+    pub fn clear_ops(&mut self) {
+        self.ops.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_ops(&mut self, v: ::protobuf::RepeatedField<super::playlist4ops::Op>) {
+        self.ops = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_ops(&mut self) -> &mut ::protobuf::RepeatedField<super::playlist4ops::Op> {
+        &mut self.ops
+    }
+
+    // Take field
+    pub fn take_ops(&mut self) -> ::protobuf::RepeatedField<super::playlist4ops::Op> {
+        ::std::mem::replace(&mut self.ops, ::protobuf::RepeatedField::new())
+    }
+
+    // optional bytes to_revision = 3;
+
+
+    pub fn get_to_revision(&self) -> &[u8] {
+        match self.to_revision.as_ref() {
+            Some(v) => &v,
+            None => &[],
+        }
+    }
+    pub fn clear_to_revision(&mut self) {
+        self.to_revision.clear();
+    }
+
+    pub fn has_to_revision(&self) -> bool {
+        self.to_revision.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_to_revision(&mut self, v: ::std::vec::Vec<u8>) {
+        self.to_revision = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_to_revision(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.to_revision.is_none() {
+            self.to_revision.set_default();
+        }
+        self.to_revision.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_to_revision(&mut self) -> ::std::vec::Vec<u8> {
+        self.to_revision.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    }
+}
+
+impl ::protobuf::Message for Diff {
+    fn is_initialized(&self) -> bool {
+        for v in &self.ops {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.from_revision)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.ops)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.to_revision)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.from_revision.as_ref() {
+            my_size += ::protobuf::rt::bytes_size(1, &v);
+        }
+        for value in &self.ops {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        if let Some(ref v) = self.to_revision.as_ref() {
+            my_size += ::protobuf::rt::bytes_size(3, &v);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.from_revision.as_ref() {
+            os.write_bytes(1, &v)?;
+        }
+        for v in &self.ops {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        if let Some(ref v) = self.to_revision.as_ref() {
+            os.write_bytes(3, &v)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> Diff {
+        Diff::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                    "from_revision",
+                    |m: &Diff| { &m.from_revision },
+                    |m: &mut Diff| { &mut m.from_revision },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4ops::Op>>(
+                    "ops",
+                    |m: &Diff| { &m.ops },
+                    |m: &mut Diff| { &mut m.ops },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                    "to_revision",
+                    |m: &Diff| { &m.to_revision },
+                    |m: &mut Diff| { &mut m.to_revision },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<Diff>(
+                    "Diff",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static Diff {
+        static mut instance: ::protobuf::lazy::Lazy<Diff> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const Diff,
+        };
+        unsafe {
+            instance.get(Diff::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for Diff {
+    fn clear(&mut self) {
+        self.from_revision.clear();
+        self.ops.clear();
+        self.to_revision.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for Diff {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for Diff {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ListDump {
+    // message fields
+    latestRevision: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+    length: ::std::option::Option<i32>,
+    attributes: ::protobuf::SingularPtrField<super::playlist4meta::ListAttributes>,
+    checksum: ::protobuf::SingularPtrField<super::playlist4meta::ListChecksum>,
+    contents: ::protobuf::SingularPtrField<super::playlist4content::ListItems>,
+    pendingDeltas: ::protobuf::RepeatedField<Delta>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ListDump {
+    fn default() -> &'a ListDump {
+        <ListDump as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ListDump {
+    pub fn new() -> ListDump {
+        ::std::default::Default::default()
+    }
+
+    // optional bytes latestRevision = 1;
+
+
+    pub fn get_latestRevision(&self) -> &[u8] {
+        match self.latestRevision.as_ref() {
+            Some(v) => &v,
+            None => &[],
+        }
+    }
+    pub fn clear_latestRevision(&mut self) {
+        self.latestRevision.clear();
+    }
+
+    pub fn has_latestRevision(&self) -> bool {
+        self.latestRevision.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_latestRevision(&mut self, v: ::std::vec::Vec<u8>) {
+        self.latestRevision = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_latestRevision(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.latestRevision.is_none() {
+            self.latestRevision.set_default();
+        }
+        self.latestRevision.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_latestRevision(&mut self) -> ::std::vec::Vec<u8> {
+        self.latestRevision.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    }
+
+    // optional int32 length = 2;
+
+
+    pub fn get_length(&self) -> i32 {
+        self.length.unwrap_or(0)
+    }
+    pub fn clear_length(&mut self) {
+        self.length = ::std::option::Option::None;
+    }
+
+    pub fn has_length(&self) -> bool {
+        self.length.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_length(&mut self, v: i32) {
+        self.length = ::std::option::Option::Some(v);
+    }
+
+    // optional .ListAttributes attributes = 3;
+
+
+    pub fn get_attributes(&self) -> &super::playlist4meta::ListAttributes {
+        self.attributes.as_ref().unwrap_or_else(|| super::playlist4meta::ListAttributes::default_instance())
+    }
+    pub fn clear_attributes(&mut self) {
+        self.attributes.clear();
+    }
+
+    pub fn has_attributes(&self) -> bool {
+        self.attributes.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_attributes(&mut self, v: super::playlist4meta::ListAttributes) {
+        self.attributes = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_attributes(&mut self) -> &mut super::playlist4meta::ListAttributes {
+        if self.attributes.is_none() {
+            self.attributes.set_default();
+        }
+        self.attributes.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_attributes(&mut self) -> super::playlist4meta::ListAttributes {
+        self.attributes.take().unwrap_or_else(|| super::playlist4meta::ListAttributes::new())
+    }
+
+    // optional .ListChecksum checksum = 4;
+
+
+    pub fn get_checksum(&self) -> &super::playlist4meta::ListChecksum {
+        self.checksum.as_ref().unwrap_or_else(|| super::playlist4meta::ListChecksum::default_instance())
+    }
+    pub fn clear_checksum(&mut self) {
+        self.checksum.clear();
+    }
+
+    pub fn has_checksum(&self) -> bool {
+        self.checksum.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_checksum(&mut self, v: super::playlist4meta::ListChecksum) {
+        self.checksum = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_checksum(&mut self) -> &mut super::playlist4meta::ListChecksum {
+        if self.checksum.is_none() {
+            self.checksum.set_default();
+        }
+        self.checksum.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_checksum(&mut self) -> super::playlist4meta::ListChecksum {
+        self.checksum.take().unwrap_or_else(|| super::playlist4meta::ListChecksum::new())
+    }
+
+    // optional .ListItems contents = 5;
+
+
+    pub fn get_contents(&self) -> &super::playlist4content::ListItems {
+        self.contents.as_ref().unwrap_or_else(|| super::playlist4content::ListItems::default_instance())
+    }
+    pub fn clear_contents(&mut self) {
+        self.contents.clear();
+    }
+
+    pub fn has_contents(&self) -> bool {
+        self.contents.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_contents(&mut self, v: super::playlist4content::ListItems) {
+        self.contents = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_contents(&mut self) -> &mut super::playlist4content::ListItems {
+        if self.contents.is_none() {
+            self.contents.set_default();
+        }
+        self.contents.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_contents(&mut self) -> super::playlist4content::ListItems {
+        self.contents.take().unwrap_or_else(|| super::playlist4content::ListItems::new())
+    }
+
+    // repeated .Delta pendingDeltas = 7;
+
+
+    pub fn get_pendingDeltas(&self) -> &[Delta] {
+        &self.pendingDeltas
+    }
+    pub fn clear_pendingDeltas(&mut self) {
+        self.pendingDeltas.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_pendingDeltas(&mut self, v: ::protobuf::RepeatedField<Delta>) {
+        self.pendingDeltas = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_pendingDeltas(&mut self) -> &mut ::protobuf::RepeatedField<Delta> {
+        &mut self.pendingDeltas
+    }
+
+    // Take field
+    pub fn take_pendingDeltas(&mut self) -> ::protobuf::RepeatedField<Delta> {
+        ::std::mem::replace(&mut self.pendingDeltas, ::protobuf::RepeatedField::new())
+    }
+}
+
+impl ::protobuf::Message for ListDump {
+    fn is_initialized(&self) -> bool {
+        for v in &self.attributes {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.checksum {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.contents {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.pendingDeltas {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.latestRevision)?;
+                },
+                2 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.length = ::std::option::Option::Some(tmp);
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.attributes)?;
+                },
+                4 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.checksum)?;
+                },
+                5 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.contents)?;
+                },
+                7 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.pendingDeltas)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.latestRevision.as_ref() {
+            my_size += ::protobuf::rt::bytes_size(1, &v);
+        }
+        if let Some(v) = self.length {
+            my_size += ::protobuf::rt::value_size(2, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(ref v) = self.attributes.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.checksum.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.contents.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        for value in &self.pendingDeltas {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.latestRevision.as_ref() {
+            os.write_bytes(1, &v)?;
+        }
+        if let Some(v) = self.length {
+            os.write_int32(2, v)?;
+        }
+        if let Some(ref v) = self.attributes.as_ref() {
+            os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.checksum.as_ref() {
+            os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.contents.as_ref() {
+            os.write_tag(5, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        for v in &self.pendingDeltas {
+            os.write_tag(7, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ListDump {
+        ListDump::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                    "latestRevision",
+                    |m: &ListDump| { &m.latestRevision },
+                    |m: &mut ListDump| { &mut m.latestRevision },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "length",
+                    |m: &ListDump| { &m.length },
+                    |m: &mut ListDump| { &mut m.length },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListAttributes>>(
+                    "attributes",
+                    |m: &ListDump| { &m.attributes },
+                    |m: &mut ListDump| { &mut m.attributes },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListChecksum>>(
+                    "checksum",
+                    |m: &ListDump| { &m.checksum },
+                    |m: &mut ListDump| { &mut m.checksum },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4content::ListItems>>(
+                    "contents",
+                    |m: &ListDump| { &m.contents },
+                    |m: &mut ListDump| { &mut m.contents },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Delta>>(
+                    "pendingDeltas",
+                    |m: &ListDump| { &m.pendingDeltas },
+                    |m: &mut ListDump| { &mut m.pendingDeltas },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<ListDump>(
+                    "ListDump",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static ListDump {
+        static mut instance: ::protobuf::lazy::Lazy<ListDump> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ListDump,
+        };
+        unsafe {
+            instance.get(ListDump::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for ListDump {
+    fn clear(&mut self) {
+        self.latestRevision.clear();
+        self.length = ::std::option::Option::None;
+        self.attributes.clear();
+        self.checksum.clear();
+        self.contents.clear();
+        self.pendingDeltas.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ListDump {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ListDump {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ListChanges {
+    // message fields
+    baseRevision: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+    deltas: ::protobuf::RepeatedField<Delta>,
+    wantResultingRevisions: ::std::option::Option<bool>,
+    wantSyncResult: ::std::option::Option<bool>,
+    dump: ::protobuf::SingularPtrField<ListDump>,
+    nonces: ::std::vec::Vec<i32>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ListChanges {
+    fn default() -> &'a ListChanges {
+        <ListChanges as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ListChanges {
+    pub fn new() -> ListChanges {
+        ::std::default::Default::default()
+    }
+
+    // optional bytes baseRevision = 1;
+
+
+    pub fn get_baseRevision(&self) -> &[u8] {
+        match self.baseRevision.as_ref() {
+            Some(v) => &v,
+            None => &[],
+        }
+    }
+    pub fn clear_baseRevision(&mut self) {
+        self.baseRevision.clear();
+    }
+
+    pub fn has_baseRevision(&self) -> bool {
+        self.baseRevision.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_baseRevision(&mut self, v: ::std::vec::Vec<u8>) {
+        self.baseRevision = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_baseRevision(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.baseRevision.is_none() {
+            self.baseRevision.set_default();
+        }
+        self.baseRevision.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_baseRevision(&mut self) -> ::std::vec::Vec<u8> {
+        self.baseRevision.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    }
+
+    // repeated .Delta deltas = 2;
+
+
+    pub fn get_deltas(&self) -> &[Delta] {
+        &self.deltas
+    }
+    pub fn clear_deltas(&mut self) {
+        self.deltas.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_deltas(&mut self, v: ::protobuf::RepeatedField<Delta>) {
+        self.deltas = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_deltas(&mut self) -> &mut ::protobuf::RepeatedField<Delta> {
+        &mut self.deltas
+    }
+
+    // Take field
+    pub fn take_deltas(&mut self) -> ::protobuf::RepeatedField<Delta> {
+        ::std::mem::replace(&mut self.deltas, ::protobuf::RepeatedField::new())
+    }
+
+    // optional bool wantResultingRevisions = 3;
+
+
+    pub fn get_wantResultingRevisions(&self) -> bool {
+        self.wantResultingRevisions.unwrap_or(false)
+    }
+    pub fn clear_wantResultingRevisions(&mut self) {
+        self.wantResultingRevisions = ::std::option::Option::None;
+    }
+
+    pub fn has_wantResultingRevisions(&self) -> bool {
+        self.wantResultingRevisions.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_wantResultingRevisions(&mut self, v: bool) {
+        self.wantResultingRevisions = ::std::option::Option::Some(v);
+    }
+
+    // optional bool wantSyncResult = 4;
+
+
+    pub fn get_wantSyncResult(&self) -> bool {
+        self.wantSyncResult.unwrap_or(false)
+    }
+    pub fn clear_wantSyncResult(&mut self) {
+        self.wantSyncResult = ::std::option::Option::None;
+    }
+
+    pub fn has_wantSyncResult(&self) -> bool {
+        self.wantSyncResult.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_wantSyncResult(&mut self, v: bool) {
+        self.wantSyncResult = ::std::option::Option::Some(v);
+    }
+
+    // optional .ListDump dump = 5;
+
+
+    pub fn get_dump(&self) -> &ListDump {
+        self.dump.as_ref().unwrap_or_else(|| ListDump::default_instance())
+    }
+    pub fn clear_dump(&mut self) {
+        self.dump.clear();
+    }
+
+    pub fn has_dump(&self) -> bool {
+        self.dump.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_dump(&mut self, v: ListDump) {
+        self.dump = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_dump(&mut self) -> &mut ListDump {
+        if self.dump.is_none() {
+            self.dump.set_default();
+        }
+        self.dump.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_dump(&mut self) -> ListDump {
+        self.dump.take().unwrap_or_else(|| ListDump::new())
+    }
+
+    // repeated int32 nonces = 6;
+
+
+    pub fn get_nonces(&self) -> &[i32] {
+        &self.nonces
+    }
+    pub fn clear_nonces(&mut self) {
+        self.nonces.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_nonces(&mut self, v: ::std::vec::Vec<i32>) {
+        self.nonces = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_nonces(&mut self) -> &mut ::std::vec::Vec<i32> {
+        &mut self.nonces
+    }
+
+    // Take field
+    pub fn take_nonces(&mut self) -> ::std::vec::Vec<i32> {
+        ::std::mem::replace(&mut self.nonces, ::std::vec::Vec::new())
+    }
+}
+
+impl ::protobuf::Message for ListChanges {
+    fn is_initialized(&self) -> bool {
+        for v in &self.deltas {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.dump {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.baseRevision)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.deltas)?;
+                },
+                3 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.wantResultingRevisions = ::std::option::Option::Some(tmp);
+                },
+                4 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.wantSyncResult = ::std::option::Option::Some(tmp);
+                },
+                5 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.dump)?;
+                },
+                6 => {
+                    ::protobuf::rt::read_repeated_int32_into(wire_type, is, &mut self.nonces)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.baseRevision.as_ref() {
+            my_size += ::protobuf::rt::bytes_size(1, &v);
+        }
+        for value in &self.deltas {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        if let Some(v) = self.wantResultingRevisions {
+            my_size += 2;
+        }
+        if let Some(v) = self.wantSyncResult {
+            my_size += 2;
+        }
+        if let Some(ref v) = self.dump.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        for value in &self.nonces {
+            my_size += ::protobuf::rt::value_size(6, *value, ::protobuf::wire_format::WireTypeVarint);
+        };
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.baseRevision.as_ref() {
+            os.write_bytes(1, &v)?;
+        }
+        for v in &self.deltas {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        if let Some(v) = self.wantResultingRevisions {
+            os.write_bool(3, v)?;
+        }
+        if let Some(v) = self.wantSyncResult {
+            os.write_bool(4, v)?;
+        }
+        if let Some(ref v) = self.dump.as_ref() {
+            os.write_tag(5, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        for v in &self.nonces {
+            os.write_int32(6, *v)?;
+        };
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ListChanges {
+        ListChanges::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                    "baseRevision",
+                    |m: &ListChanges| { &m.baseRevision },
+                    |m: &mut ListChanges| { &mut m.baseRevision },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Delta>>(
+                    "deltas",
+                    |m: &ListChanges| { &m.deltas },
+                    |m: &mut ListChanges| { &mut m.deltas },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "wantResultingRevisions",
+                    |m: &ListChanges| { &m.wantResultingRevisions },
+                    |m: &mut ListChanges| { &mut m.wantResultingRevisions },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "wantSyncResult",
+                    |m: &ListChanges| { &m.wantSyncResult },
+                    |m: &mut ListChanges| { &mut m.wantSyncResult },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ListDump>>(
+                    "dump",
+                    |m: &ListChanges| { &m.dump },
+                    |m: &mut ListChanges| { &mut m.dump },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_vec_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "nonces",
+                    |m: &ListChanges| { &m.nonces },
+                    |m: &mut ListChanges| { &mut m.nonces },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<ListChanges>(
+                    "ListChanges",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static ListChanges {
+        static mut instance: ::protobuf::lazy::Lazy<ListChanges> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ListChanges,
+        };
+        unsafe {
+            instance.get(ListChanges::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for ListChanges {
+    fn clear(&mut self) {
+        self.baseRevision.clear();
+        self.deltas.clear();
+        self.wantResultingRevisions = ::std::option::Option::None;
+        self.wantSyncResult = ::std::option::Option::None;
+        self.dump.clear();
+        self.nonces.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ListChanges {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ListChanges {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct SelectedListContent {
+    // message fields
+    revision: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+    length: ::std::option::Option<i32>,
+    attributes: ::protobuf::SingularPtrField<super::playlist4meta::ListAttributes>,
+    checksum: ::protobuf::SingularPtrField<super::playlist4meta::ListChecksum>,
+    contents: ::protobuf::SingularPtrField<super::playlist4content::ListItems>,
+    diff: ::protobuf::SingularPtrField<Diff>,
+    syncResult: ::protobuf::SingularPtrField<Diff>,
+    resultingRevisions: ::protobuf::RepeatedField<::std::vec::Vec<u8>>,
+    multipleHeads: ::std::option::Option<bool>,
+    upToDate: ::std::option::Option<bool>,
+    resolveAction: ::protobuf::RepeatedField<super::playlist4issues::ClientResolveAction>,
+    issues: ::protobuf::RepeatedField<super::playlist4issues::ClientIssue>,
+    nonces: ::std::vec::Vec<i32>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a SelectedListContent {
+    fn default() -> &'a SelectedListContent {
+        <SelectedListContent as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl SelectedListContent {
+    pub fn new() -> SelectedListContent {
+        ::std::default::Default::default()
+    }
+
+    // optional bytes revision = 1;
+
+
+    pub fn get_revision(&self) -> &[u8] {
+        match self.revision.as_ref() {
+            Some(v) => &v,
+            None => &[],
+        }
+    }
+    pub fn clear_revision(&mut self) {
+        self.revision.clear();
+    }
+
+    pub fn has_revision(&self) -> bool {
+        self.revision.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_revision(&mut self, v: ::std::vec::Vec<u8>) {
+        self.revision = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_revision(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.revision.is_none() {
+            self.revision.set_default();
+        }
+        self.revision.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_revision(&mut self) -> ::std::vec::Vec<u8> {
+        self.revision.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    }
+
+    // optional int32 length = 2;
+
+
+    pub fn get_length(&self) -> i32 {
+        self.length.unwrap_or(0)
+    }
+    pub fn clear_length(&mut self) {
+        self.length = ::std::option::Option::None;
+    }
+
+    pub fn has_length(&self) -> bool {
+        self.length.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_length(&mut self, v: i32) {
+        self.length = ::std::option::Option::Some(v);
+    }
+
+    // optional .ListAttributes attributes = 3;
+
+
+    pub fn get_attributes(&self) -> &super::playlist4meta::ListAttributes {
+        self.attributes.as_ref().unwrap_or_else(|| super::playlist4meta::ListAttributes::default_instance())
+    }
+    pub fn clear_attributes(&mut self) {
+        self.attributes.clear();
+    }
+
+    pub fn has_attributes(&self) -> bool {
+        self.attributes.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_attributes(&mut self, v: super::playlist4meta::ListAttributes) {
+        self.attributes = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_attributes(&mut self) -> &mut super::playlist4meta::ListAttributes {
+        if self.attributes.is_none() {
+            self.attributes.set_default();
+        }
+        self.attributes.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_attributes(&mut self) -> super::playlist4meta::ListAttributes {
+        self.attributes.take().unwrap_or_else(|| super::playlist4meta::ListAttributes::new())
+    }
+
+    // optional .ListChecksum checksum = 4;
+
+
+    pub fn get_checksum(&self) -> &super::playlist4meta::ListChecksum {
+        self.checksum.as_ref().unwrap_or_else(|| super::playlist4meta::ListChecksum::default_instance())
+    }
+    pub fn clear_checksum(&mut self) {
+        self.checksum.clear();
+    }
+
+    pub fn has_checksum(&self) -> bool {
+        self.checksum.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_checksum(&mut self, v: super::playlist4meta::ListChecksum) {
+        self.checksum = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_checksum(&mut self) -> &mut super::playlist4meta::ListChecksum {
+        if self.checksum.is_none() {
+            self.checksum.set_default();
+        }
+        self.checksum.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_checksum(&mut self) -> super::playlist4meta::ListChecksum {
+        self.checksum.take().unwrap_or_else(|| super::playlist4meta::ListChecksum::new())
+    }
+
+    // optional .ListItems contents = 5;
+
+
+    pub fn get_contents(&self) -> &super::playlist4content::ListItems {
+        self.contents.as_ref().unwrap_or_else(|| super::playlist4content::ListItems::default_instance())
+    }
+    pub fn clear_contents(&mut self) {
+        self.contents.clear();
+    }
+
+    pub fn has_contents(&self) -> bool {
+        self.contents.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_contents(&mut self, v: super::playlist4content::ListItems) {
+        self.contents = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_contents(&mut self) -> &mut super::playlist4content::ListItems {
+        if self.contents.is_none() {
+            self.contents.set_default();
+        }
+        self.contents.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_contents(&mut self) -> super::playlist4content::ListItems {
+        self.contents.take().unwrap_or_else(|| super::playlist4content::ListItems::new())
+    }
+
+    // optional .Diff diff = 6;
+
+
+    pub fn get_diff(&self) -> &Diff {
+        self.diff.as_ref().unwrap_or_else(|| Diff::default_instance())
+    }
+    pub fn clear_diff(&mut self) {
+        self.diff.clear();
+    }
+
+    pub fn has_diff(&self) -> bool {
+        self.diff.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_diff(&mut self, v: Diff) {
+        self.diff = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_diff(&mut self) -> &mut Diff {
+        if self.diff.is_none() {
+            self.diff.set_default();
+        }
+        self.diff.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_diff(&mut self) -> Diff {
+        self.diff.take().unwrap_or_else(|| Diff::new())
+    }
+
+    // optional .Diff syncResult = 7;
+
+
+    pub fn get_syncResult(&self) -> &Diff {
+        self.syncResult.as_ref().unwrap_or_else(|| Diff::default_instance())
+    }
+    pub fn clear_syncResult(&mut self) {
+        self.syncResult.clear();
+    }
+
+    pub fn has_syncResult(&self) -> bool {
+        self.syncResult.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_syncResult(&mut self, v: Diff) {
+        self.syncResult = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_syncResult(&mut self) -> &mut Diff {
+        if self.syncResult.is_none() {
+            self.syncResult.set_default();
+        }
+        self.syncResult.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_syncResult(&mut self) -> Diff {
+        self.syncResult.take().unwrap_or_else(|| Diff::new())
+    }
+
+    // repeated bytes resultingRevisions = 8;
+
+
+    pub fn get_resultingRevisions(&self) -> &[::std::vec::Vec<u8>] {
+        &self.resultingRevisions
+    }
+    pub fn clear_resultingRevisions(&mut self) {
+        self.resultingRevisions.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_resultingRevisions(&mut self, v: ::protobuf::RepeatedField<::std::vec::Vec<u8>>) {
+        self.resultingRevisions = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_resultingRevisions(&mut self) -> &mut ::protobuf::RepeatedField<::std::vec::Vec<u8>> {
+        &mut self.resultingRevisions
+    }
+
+    // Take field
+    pub fn take_resultingRevisions(&mut self) -> ::protobuf::RepeatedField<::std::vec::Vec<u8>> {
+        ::std::mem::replace(&mut self.resultingRevisions, ::protobuf::RepeatedField::new())
+    }
+
+    // optional bool multipleHeads = 9;
+
+
+    pub fn get_multipleHeads(&self) -> bool {
+        self.multipleHeads.unwrap_or(false)
+    }
+    pub fn clear_multipleHeads(&mut self) {
+        self.multipleHeads = ::std::option::Option::None;
+    }
+
+    pub fn has_multipleHeads(&self) -> bool {
+        self.multipleHeads.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_multipleHeads(&mut self, v: bool) {
+        self.multipleHeads = ::std::option::Option::Some(v);
+    }
+
+    // optional bool upToDate = 10;
+
+
+    pub fn get_upToDate(&self) -> bool {
+        self.upToDate.unwrap_or(false)
+    }
+    pub fn clear_upToDate(&mut self) {
+        self.upToDate = ::std::option::Option::None;
+    }
+
+    pub fn has_upToDate(&self) -> bool {
+        self.upToDate.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_upToDate(&mut self, v: bool) {
+        self.upToDate = ::std::option::Option::Some(v);
+    }
+
+    // repeated .ClientResolveAction resolveAction = 12;
+
+
+    pub fn get_resolveAction(&self) -> &[super::playlist4issues::ClientResolveAction] {
+        &self.resolveAction
+    }
+    pub fn clear_resolveAction(&mut self) {
+        self.resolveAction.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_resolveAction(&mut self, v: ::protobuf::RepeatedField<super::playlist4issues::ClientResolveAction>) {
+        self.resolveAction = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_resolveAction(&mut self) -> &mut ::protobuf::RepeatedField<super::playlist4issues::ClientResolveAction> {
+        &mut self.resolveAction
+    }
+
+    // Take field
+    pub fn take_resolveAction(&mut self) -> ::protobuf::RepeatedField<super::playlist4issues::ClientResolveAction> {
+        ::std::mem::replace(&mut self.resolveAction, ::protobuf::RepeatedField::new())
+    }
+
+    // repeated .ClientIssue issues = 13;
+
+
+    pub fn get_issues(&self) -> &[super::playlist4issues::ClientIssue] {
+        &self.issues
+    }
+    pub fn clear_issues(&mut self) {
+        self.issues.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_issues(&mut self, v: ::protobuf::RepeatedField<super::playlist4issues::ClientIssue>) {
+        self.issues = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_issues(&mut self) -> &mut ::protobuf::RepeatedField<super::playlist4issues::ClientIssue> {
+        &mut self.issues
+    }
+
+    // Take field
+    pub fn take_issues(&mut self) -> ::protobuf::RepeatedField<super::playlist4issues::ClientIssue> {
+        ::std::mem::replace(&mut self.issues, ::protobuf::RepeatedField::new())
+    }
+
+    // repeated int32 nonces = 14;
+
+
+    pub fn get_nonces(&self) -> &[i32] {
+        &self.nonces
+    }
+    pub fn clear_nonces(&mut self) {
+        self.nonces.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_nonces(&mut self, v: ::std::vec::Vec<i32>) {
+        self.nonces = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_nonces(&mut self) -> &mut ::std::vec::Vec<i32> {
+        &mut self.nonces
+    }
+
+    // Take field
+    pub fn take_nonces(&mut self) -> ::std::vec::Vec<i32> {
+        ::std::mem::replace(&mut self.nonces, ::std::vec::Vec::new())
+    }
+}
+
+impl ::protobuf::Message for SelectedListContent {
+    fn is_initialized(&self) -> bool {
+        for v in &self.attributes {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.checksum {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.contents {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.diff {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.syncResult {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.resolveAction {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.issues {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.revision)?;
+                },
+                2 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.length = ::std::option::Option::Some(tmp);
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.attributes)?;
+                },
+                4 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.checksum)?;
+                },
+                5 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.contents)?;
+                },
+                6 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.diff)?;
+                },
+                7 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.syncResult)?;
+                },
+                8 => {
+                    ::protobuf::rt::read_repeated_bytes_into(wire_type, is, &mut self.resultingRevisions)?;
+                },
+                9 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.multipleHeads = ::std::option::Option::Some(tmp);
+                },
+                10 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.upToDate = ::std::option::Option::Some(tmp);
+                },
+                12 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.resolveAction)?;
+                },
+                13 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.issues)?;
+                },
+                14 => {
+                    ::protobuf::rt::read_repeated_int32_into(wire_type, is, &mut self.nonces)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.revision.as_ref() {
+            my_size += ::protobuf::rt::bytes_size(1, &v);
+        }
+        if let Some(v) = self.length {
+            my_size += ::protobuf::rt::value_size(2, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(ref v) = self.attributes.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.checksum.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.contents.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.diff.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.syncResult.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        for value in &self.resultingRevisions {
+            my_size += ::protobuf::rt::bytes_size(8, &value);
+        };
+        if let Some(v) = self.multipleHeads {
+            my_size += 2;
+        }
+        if let Some(v) = self.upToDate {
+            my_size += 2;
+        }
+        for value in &self.resolveAction {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        for value in &self.issues {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        for value in &self.nonces {
+            my_size += ::protobuf::rt::value_size(14, *value, ::protobuf::wire_format::WireTypeVarint);
+        };
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.revision.as_ref() {
+            os.write_bytes(1, &v)?;
+        }
+        if let Some(v) = self.length {
+            os.write_int32(2, v)?;
+        }
+        if let Some(ref v) = self.attributes.as_ref() {
+            os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.checksum.as_ref() {
+            os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.contents.as_ref() {
+            os.write_tag(5, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.diff.as_ref() {
+            os.write_tag(6, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.syncResult.as_ref() {
+            os.write_tag(7, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        for v in &self.resultingRevisions {
+            os.write_bytes(8, &v)?;
+        };
+        if let Some(v) = self.multipleHeads {
+            os.write_bool(9, v)?;
+        }
+        if let Some(v) = self.upToDate {
+            os.write_bool(10, v)?;
+        }
+        for v in &self.resolveAction {
+            os.write_tag(12, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        for v in &self.issues {
+            os.write_tag(13, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        for v in &self.nonces {
+            os.write_int32(14, *v)?;
+        };
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> SelectedListContent {
+        SelectedListContent::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                    "revision",
+                    |m: &SelectedListContent| { &m.revision },
+                    |m: &mut SelectedListContent| { &mut m.revision },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "length",
+                    |m: &SelectedListContent| { &m.length },
+                    |m: &mut SelectedListContent| { &mut m.length },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListAttributes>>(
+                    "attributes",
+                    |m: &SelectedListContent| { &m.attributes },
+                    |m: &mut SelectedListContent| { &mut m.attributes },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListChecksum>>(
+                    "checksum",
+                    |m: &SelectedListContent| { &m.checksum },
+                    |m: &mut SelectedListContent| { &mut m.checksum },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4content::ListItems>>(
+                    "contents",
+                    |m: &SelectedListContent| { &m.contents },
+                    |m: &mut SelectedListContent| { &mut m.contents },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Diff>>(
+                    "diff",
+                    |m: &SelectedListContent| { &m.diff },
+                    |m: &mut SelectedListContent| { &mut m.diff },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Diff>>(
+                    "syncResult",
+                    |m: &SelectedListContent| { &m.syncResult },
+                    |m: &mut SelectedListContent| { &mut m.syncResult },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                    "resultingRevisions",
+                    |m: &SelectedListContent| { &m.resultingRevisions },
+                    |m: &mut SelectedListContent| { &mut m.resultingRevisions },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "multipleHeads",
+                    |m: &SelectedListContent| { &m.multipleHeads },
+                    |m: &mut SelectedListContent| { &mut m.multipleHeads },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "upToDate",
+                    |m: &SelectedListContent| { &m.upToDate },
+                    |m: &mut SelectedListContent| { &mut m.upToDate },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4issues::ClientResolveAction>>(
+                    "resolveAction",
+                    |m: &SelectedListContent| { &m.resolveAction },
+                    |m: &mut SelectedListContent| { &mut m.resolveAction },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4issues::ClientIssue>>(
+                    "issues",
+                    |m: &SelectedListContent| { &m.issues },
+                    |m: &mut SelectedListContent| { &mut m.issues },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_vec_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "nonces",
+                    |m: &SelectedListContent| { &m.nonces },
+                    |m: &mut SelectedListContent| { &mut m.nonces },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<SelectedListContent>(
+                    "SelectedListContent",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static SelectedListContent {
+        static mut instance: ::protobuf::lazy::Lazy<SelectedListContent> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const SelectedListContent,
+        };
+        unsafe {
+            instance.get(SelectedListContent::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for SelectedListContent {
+    fn clear(&mut self) {
+        self.revision.clear();
+        self.length = ::std::option::Option::None;
+        self.attributes.clear();
+        self.checksum.clear();
+        self.contents.clear();
+        self.diff.clear();
+        self.syncResult.clear();
+        self.resultingRevisions.clear();
+        self.multipleHeads = ::std::option::Option::None;
+        self.upToDate = ::std::option::Option::None;
+        self.resolveAction.clear();
+        self.issues.clear();
+        self.nonces.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for SelectedListContent {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for SelectedListContent {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+static file_descriptor_proto_data: &'static [u8] = b"\
+    \n\x16playlist4changes.proto\x12\0\"\xa0\x01\n\nChangeInfo\x12\x0e\n\x04\
+    user\x18\x01\x20\x01(\tB\0\x12\x13\n\ttimestamp\x18\x02\x20\x01(\x05B\0\
+    \x12\x0f\n\x05admin\x18\x03\x20\x01(\x08B\0\x12\x0e\n\x04undo\x18\x04\
+    \x20\x01(\x08B\0\x12\x0e\n\x04redo\x18\x05\x20\x01(\x08B\0\x12\x0f\n\x05\
+    merge\x18\x06\x20\x01(\x08B\0\x12\x14\n\ncompressed\x18\x07\x20\x01(\x08\
+    B\0\x12\x13\n\tmigration\x18\x08\x20\x01(\x08B\0:\0\"R\n\x05Delta\x12\
+    \x16\n\x0cbase_version\x18\x01\x20\x01(\x0cB\0\x12\x12\n\x03ops\x18\x02\
+    \x20\x03(\x0b2\x03.OpB\0\x12\x1b\n\x04info\x18\x04\x20\x01(\x0b2\x0b.Cha\
+    ngeInfoB\0:\0\"W\n\x05Merge\x12\x16\n\x0cbase_version\x18\x01\x20\x01(\
+    \x0cB\0\x12\x17\n\rmerge_version\x18\x02\x20\x01(\x0cB\0\x12\x1b\n\x04in\
+    fo\x18\x04\x20\x01(\x0b2\x0b.ChangeInfoB\0:\0\"\x92\x01\n\tChangeSet\x12\
+    \x1f\n\x04kind\x18\x01\x20\x01(\x0e2\x0f.ChangeSet.KindB\0\x12\x17\n\x05\
+    delta\x18\x02\x20\x01(\x0b2\x06.DeltaB\0\x12\x17\n\x05merge\x18\x03\x20\
+    \x01(\x0b2\x06.MergeB\0\"0\n\x04Kind\x12\x10\n\x0cKIND_UNKNOWN\x10\0\x12\
+    \t\n\x05DELTA\x10\x02\x12\t\n\x05MERGE\x10\x03\x1a\0:\0\"Q\n\x17Revision\
+    TaggedChangeSet\x12\x12\n\x08revision\x18\x01\x20\x01(\x0cB\0\x12\x20\n\
+    \nchange_set\x18\x02\x20\x01(\x0b2\n.ChangeSetB\0:\0\"L\n\x04Diff\x12\
+    \x17\n\rfrom_revision\x18\x01\x20\x01(\x0cB\0\x12\x12\n\x03ops\x18\x02\
+    \x20\x03(\x0b2\x03.OpB\0\x12\x15\n\x0bto_revision\x18\x03\x20\x01(\x0cB\
+    \0:\0\"\xc3\x01\n\x08ListDump\x12\x18\n\x0elatestRevision\x18\x01\x20\
+    \x01(\x0cB\0\x12\x10\n\x06length\x18\x02\x20\x01(\x05B\0\x12%\n\nattribu\
+    tes\x18\x03\x20\x01(\x0b2\x0f.ListAttributesB\0\x12!\n\x08checksum\x18\
+    \x04\x20\x01(\x0b2\r.ListChecksumB\0\x12\x1e\n\x08contents\x18\x05\x20\
+    \x01(\x0b2\n.ListItemsB\0\x12\x1f\n\rpendingDeltas\x18\x07\x20\x03(\x0b2\
+    \x06.DeltaB\0:\0\"\xaa\x01\n\x0bListChanges\x12\x16\n\x0cbaseRevision\
+    \x18\x01\x20\x01(\x0cB\0\x12\x18\n\x06deltas\x18\x02\x20\x03(\x0b2\x06.D\
+    eltaB\0\x12\x20\n\x16wantResultingRevisions\x18\x03\x20\x01(\x08B\0\x12\
+    \x18\n\x0ewantSyncResult\x18\x04\x20\x01(\x08B\0\x12\x19\n\x04dump\x18\
+    \x05\x20\x01(\x0b2\t.ListDumpB\0\x12\x10\n\x06nonces\x18\x06\x20\x03(\
+    \x05B\0:\0\"\x87\x03\n\x13SelectedListContent\x12\x12\n\x08revision\x18\
+    \x01\x20\x01(\x0cB\0\x12\x10\n\x06length\x18\x02\x20\x01(\x05B\0\x12%\n\
+    \nattributes\x18\x03\x20\x01(\x0b2\x0f.ListAttributesB\0\x12!\n\x08check\
+    sum\x18\x04\x20\x01(\x0b2\r.ListChecksumB\0\x12\x1e\n\x08contents\x18\
+    \x05\x20\x01(\x0b2\n.ListItemsB\0\x12\x15\n\x04diff\x18\x06\x20\x01(\x0b\
+    2\x05.DiffB\0\x12\x1b\n\nsyncResult\x18\x07\x20\x01(\x0b2\x05.DiffB\0\
+    \x12\x1c\n\x12resultingRevisions\x18\x08\x20\x03(\x0cB\0\x12\x17\n\rmult\
+    ipleHeads\x18\t\x20\x01(\x08B\0\x12\x12\n\x08upToDate\x18\n\x20\x01(\x08\
+    B\0\x12-\n\rresolveAction\x18\x0c\x20\x03(\x0b2\x14.ClientResolveActionB\
+    \0\x12\x1e\n\x06issues\x18\r\x20\x03(\x0b2\x0c.ClientIssueB\0\x12\x10\n\
+    \x06nonces\x18\x0e\x20\x03(\x05B\0:\0B\0b\x06proto2\
+";
+
+static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy {
+    lock: ::protobuf::lazy::ONCE_INIT,
+    ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto,
+};
+
+fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
+    ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()
+}
+
+pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
+    unsafe {
+        file_descriptor_proto_lazy.get(|| {
+            parse_descriptor_proto()
+        })
+    }
+}

+ 1457 - 0
protocol/src/playlist4content.rs

@@ -0,0 +1,1457 @@
+// This file is generated by rust-protobuf 2.7.0. Do not edit
+// @generated
+
+// https://github.com/Manishearth/rust-clippy/issues/702
+#![allow(unknown_lints)]
+#![allow(clippy::all)]
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+
+#![allow(box_pointers)]
+#![allow(dead_code)]
+#![allow(missing_docs)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![allow(trivial_casts)]
+#![allow(unsafe_code)]
+#![allow(unused_imports)]
+#![allow(unused_results)]
+//! Generated file from `playlist4content.proto`
+
+use protobuf::Message as Message_imported_for_functions;
+use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
+
+/// Generated files are compatible only with the same version
+/// of protobuf runtime.
+const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_7_0;
+
+#[derive(PartialEq,Clone,Default)]
+pub struct Item {
+    // message fields
+    uri: ::protobuf::SingularField<::std::string::String>,
+    attributes: ::protobuf::SingularPtrField<super::playlist4meta::ItemAttributes>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a Item {
+    fn default() -> &'a Item {
+        <Item as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl Item {
+    pub fn new() -> Item {
+        ::std::default::Default::default()
+    }
+
+    // optional string uri = 1;
+
+
+    pub fn get_uri(&self) -> &str {
+        match self.uri.as_ref() {
+            Some(v) => &v,
+            None => "",
+        }
+    }
+    pub fn clear_uri(&mut self) {
+        self.uri.clear();
+    }
+
+    pub fn has_uri(&self) -> bool {
+        self.uri.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_uri(&mut self, v: ::std::string::String) {
+        self.uri = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_uri(&mut self) -> &mut ::std::string::String {
+        if self.uri.is_none() {
+            self.uri.set_default();
+        }
+        self.uri.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_uri(&mut self) -> ::std::string::String {
+        self.uri.take().unwrap_or_else(|| ::std::string::String::new())
+    }
+
+    // optional .ItemAttributes attributes = 2;
+
+
+    pub fn get_attributes(&self) -> &super::playlist4meta::ItemAttributes {
+        self.attributes.as_ref().unwrap_or_else(|| super::playlist4meta::ItemAttributes::default_instance())
+    }
+    pub fn clear_attributes(&mut self) {
+        self.attributes.clear();
+    }
+
+    pub fn has_attributes(&self) -> bool {
+        self.attributes.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_attributes(&mut self, v: super::playlist4meta::ItemAttributes) {
+        self.attributes = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_attributes(&mut self) -> &mut super::playlist4meta::ItemAttributes {
+        if self.attributes.is_none() {
+            self.attributes.set_default();
+        }
+        self.attributes.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_attributes(&mut self) -> super::playlist4meta::ItemAttributes {
+        self.attributes.take().unwrap_or_else(|| super::playlist4meta::ItemAttributes::new())
+    }
+}
+
+impl ::protobuf::Message for Item {
+    fn is_initialized(&self) -> bool {
+        for v in &self.attributes {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.uri)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.attributes)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.uri.as_ref() {
+            my_size += ::protobuf::rt::string_size(1, &v);
+        }
+        if let Some(ref v) = self.attributes.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.uri.as_ref() {
+            os.write_string(1, &v)?;
+        }
+        if let Some(ref v) = self.attributes.as_ref() {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> Item {
+        Item::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                    "uri",
+                    |m: &Item| { &m.uri },
+                    |m: &mut Item| { &mut m.uri },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ItemAttributes>>(
+                    "attributes",
+                    |m: &Item| { &m.attributes },
+                    |m: &mut Item| { &mut m.attributes },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<Item>(
+                    "Item",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static Item {
+        static mut instance: ::protobuf::lazy::Lazy<Item> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const Item,
+        };
+        unsafe {
+            instance.get(Item::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for Item {
+    fn clear(&mut self) {
+        self.uri.clear();
+        self.attributes.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for Item {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for Item {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ListItems {
+    // message fields
+    pos: ::std::option::Option<i32>,
+    truncated: ::std::option::Option<bool>,
+    items: ::protobuf::RepeatedField<Item>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ListItems {
+    fn default() -> &'a ListItems {
+        <ListItems as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ListItems {
+    pub fn new() -> ListItems {
+        ::std::default::Default::default()
+    }
+
+    // optional int32 pos = 1;
+
+
+    pub fn get_pos(&self) -> i32 {
+        self.pos.unwrap_or(0)
+    }
+    pub fn clear_pos(&mut self) {
+        self.pos = ::std::option::Option::None;
+    }
+
+    pub fn has_pos(&self) -> bool {
+        self.pos.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_pos(&mut self, v: i32) {
+        self.pos = ::std::option::Option::Some(v);
+    }
+
+    // optional bool truncated = 2;
+
+
+    pub fn get_truncated(&self) -> bool {
+        self.truncated.unwrap_or(false)
+    }
+    pub fn clear_truncated(&mut self) {
+        self.truncated = ::std::option::Option::None;
+    }
+
+    pub fn has_truncated(&self) -> bool {
+        self.truncated.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_truncated(&mut self, v: bool) {
+        self.truncated = ::std::option::Option::Some(v);
+    }
+
+    // repeated .Item items = 3;
+
+
+    pub fn get_items(&self) -> &[Item] {
+        &self.items
+    }
+    pub fn clear_items(&mut self) {
+        self.items.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_items(&mut self, v: ::protobuf::RepeatedField<Item>) {
+        self.items = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField<Item> {
+        &mut self.items
+    }
+
+    // Take field
+    pub fn take_items(&mut self) -> ::protobuf::RepeatedField<Item> {
+        ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new())
+    }
+}
+
+impl ::protobuf::Message for ListItems {
+    fn is_initialized(&self) -> bool {
+        for v in &self.items {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.pos = ::std::option::Option::Some(tmp);
+                },
+                2 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.truncated = ::std::option::Option::Some(tmp);
+                },
+                3 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(v) = self.pos {
+            my_size += ::protobuf::rt::value_size(1, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(v) = self.truncated {
+            my_size += 2;
+        }
+        for value in &self.items {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(v) = self.pos {
+            os.write_int32(1, v)?;
+        }
+        if let Some(v) = self.truncated {
+            os.write_bool(2, v)?;
+        }
+        for v in &self.items {
+            os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ListItems {
+        ListItems::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "pos",
+                    |m: &ListItems| { &m.pos },
+                    |m: &mut ListItems| { &mut m.pos },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "truncated",
+                    |m: &ListItems| { &m.truncated },
+                    |m: &mut ListItems| { &mut m.truncated },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Item>>(
+                    "items",
+                    |m: &ListItems| { &m.items },
+                    |m: &mut ListItems| { &mut m.items },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<ListItems>(
+                    "ListItems",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static ListItems {
+        static mut instance: ::protobuf::lazy::Lazy<ListItems> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ListItems,
+        };
+        unsafe {
+            instance.get(ListItems::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for ListItems {
+    fn clear(&mut self) {
+        self.pos = ::std::option::Option::None;
+        self.truncated = ::std::option::Option::None;
+        self.items.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ListItems {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ListItems {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ContentRange {
+    // message fields
+    pos: ::std::option::Option<i32>,
+    length: ::std::option::Option<i32>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ContentRange {
+    fn default() -> &'a ContentRange {
+        <ContentRange as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ContentRange {
+    pub fn new() -> ContentRange {
+        ::std::default::Default::default()
+    }
+
+    // optional int32 pos = 1;
+
+
+    pub fn get_pos(&self) -> i32 {
+        self.pos.unwrap_or(0)
+    }
+    pub fn clear_pos(&mut self) {
+        self.pos = ::std::option::Option::None;
+    }
+
+    pub fn has_pos(&self) -> bool {
+        self.pos.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_pos(&mut self, v: i32) {
+        self.pos = ::std::option::Option::Some(v);
+    }
+
+    // optional int32 length = 2;
+
+
+    pub fn get_length(&self) -> i32 {
+        self.length.unwrap_or(0)
+    }
+    pub fn clear_length(&mut self) {
+        self.length = ::std::option::Option::None;
+    }
+
+    pub fn has_length(&self) -> bool {
+        self.length.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_length(&mut self, v: i32) {
+        self.length = ::std::option::Option::Some(v);
+    }
+}
+
+impl ::protobuf::Message for ContentRange {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.pos = ::std::option::Option::Some(tmp);
+                },
+                2 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.length = ::std::option::Option::Some(tmp);
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(v) = self.pos {
+            my_size += ::protobuf::rt::value_size(1, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(v) = self.length {
+            my_size += ::protobuf::rt::value_size(2, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(v) = self.pos {
+            os.write_int32(1, v)?;
+        }
+        if let Some(v) = self.length {
+            os.write_int32(2, v)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ContentRange {
+        ContentRange::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "pos",
+                    |m: &ContentRange| { &m.pos },
+                    |m: &mut ContentRange| { &mut m.pos },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "length",
+                    |m: &ContentRange| { &m.length },
+                    |m: &mut ContentRange| { &mut m.length },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<ContentRange>(
+                    "ContentRange",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static ContentRange {
+        static mut instance: ::protobuf::lazy::Lazy<ContentRange> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ContentRange,
+        };
+        unsafe {
+            instance.get(ContentRange::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for ContentRange {
+    fn clear(&mut self) {
+        self.pos = ::std::option::Option::None;
+        self.length = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ContentRange {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ContentRange {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ListContentSelection {
+    // message fields
+    wantRevision: ::std::option::Option<bool>,
+    wantLength: ::std::option::Option<bool>,
+    wantAttributes: ::std::option::Option<bool>,
+    wantChecksum: ::std::option::Option<bool>,
+    wantContent: ::std::option::Option<bool>,
+    contentRange: ::protobuf::SingularPtrField<ContentRange>,
+    wantDiff: ::std::option::Option<bool>,
+    baseRevision: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+    hintRevision: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+    wantNothingIfUpToDate: ::std::option::Option<bool>,
+    wantResolveAction: ::std::option::Option<bool>,
+    issues: ::protobuf::RepeatedField<super::playlist4issues::ClientIssue>,
+    resolveAction: ::protobuf::RepeatedField<super::playlist4issues::ClientResolveAction>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ListContentSelection {
+    fn default() -> &'a ListContentSelection {
+        <ListContentSelection as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ListContentSelection {
+    pub fn new() -> ListContentSelection {
+        ::std::default::Default::default()
+    }
+
+    // optional bool wantRevision = 1;
+
+
+    pub fn get_wantRevision(&self) -> bool {
+        self.wantRevision.unwrap_or(false)
+    }
+    pub fn clear_wantRevision(&mut self) {
+        self.wantRevision = ::std::option::Option::None;
+    }
+
+    pub fn has_wantRevision(&self) -> bool {
+        self.wantRevision.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_wantRevision(&mut self, v: bool) {
+        self.wantRevision = ::std::option::Option::Some(v);
+    }
+
+    // optional bool wantLength = 2;
+
+
+    pub fn get_wantLength(&self) -> bool {
+        self.wantLength.unwrap_or(false)
+    }
+    pub fn clear_wantLength(&mut self) {
+        self.wantLength = ::std::option::Option::None;
+    }
+
+    pub fn has_wantLength(&self) -> bool {
+        self.wantLength.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_wantLength(&mut self, v: bool) {
+        self.wantLength = ::std::option::Option::Some(v);
+    }
+
+    // optional bool wantAttributes = 3;
+
+
+    pub fn get_wantAttributes(&self) -> bool {
+        self.wantAttributes.unwrap_or(false)
+    }
+    pub fn clear_wantAttributes(&mut self) {
+        self.wantAttributes = ::std::option::Option::None;
+    }
+
+    pub fn has_wantAttributes(&self) -> bool {
+        self.wantAttributes.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_wantAttributes(&mut self, v: bool) {
+        self.wantAttributes = ::std::option::Option::Some(v);
+    }
+
+    // optional bool wantChecksum = 4;
+
+
+    pub fn get_wantChecksum(&self) -> bool {
+        self.wantChecksum.unwrap_or(false)
+    }
+    pub fn clear_wantChecksum(&mut self) {
+        self.wantChecksum = ::std::option::Option::None;
+    }
+
+    pub fn has_wantChecksum(&self) -> bool {
+        self.wantChecksum.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_wantChecksum(&mut self, v: bool) {
+        self.wantChecksum = ::std::option::Option::Some(v);
+    }
+
+    // optional bool wantContent = 5;
+
+
+    pub fn get_wantContent(&self) -> bool {
+        self.wantContent.unwrap_or(false)
+    }
+    pub fn clear_wantContent(&mut self) {
+        self.wantContent = ::std::option::Option::None;
+    }
+
+    pub fn has_wantContent(&self) -> bool {
+        self.wantContent.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_wantContent(&mut self, v: bool) {
+        self.wantContent = ::std::option::Option::Some(v);
+    }
+
+    // optional .ContentRange contentRange = 6;
+
+
+    pub fn get_contentRange(&self) -> &ContentRange {
+        self.contentRange.as_ref().unwrap_or_else(|| ContentRange::default_instance())
+    }
+    pub fn clear_contentRange(&mut self) {
+        self.contentRange.clear();
+    }
+
+    pub fn has_contentRange(&self) -> bool {
+        self.contentRange.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_contentRange(&mut self, v: ContentRange) {
+        self.contentRange = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_contentRange(&mut self) -> &mut ContentRange {
+        if self.contentRange.is_none() {
+            self.contentRange.set_default();
+        }
+        self.contentRange.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_contentRange(&mut self) -> ContentRange {
+        self.contentRange.take().unwrap_or_else(|| ContentRange::new())
+    }
+
+    // optional bool wantDiff = 7;
+
+
+    pub fn get_wantDiff(&self) -> bool {
+        self.wantDiff.unwrap_or(false)
+    }
+    pub fn clear_wantDiff(&mut self) {
+        self.wantDiff = ::std::option::Option::None;
+    }
+
+    pub fn has_wantDiff(&self) -> bool {
+        self.wantDiff.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_wantDiff(&mut self, v: bool) {
+        self.wantDiff = ::std::option::Option::Some(v);
+    }
+
+    // optional bytes baseRevision = 8;
+
+
+    pub fn get_baseRevision(&self) -> &[u8] {
+        match self.baseRevision.as_ref() {
+            Some(v) => &v,
+            None => &[],
+        }
+    }
+    pub fn clear_baseRevision(&mut self) {
+        self.baseRevision.clear();
+    }
+
+    pub fn has_baseRevision(&self) -> bool {
+        self.baseRevision.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_baseRevision(&mut self, v: ::std::vec::Vec<u8>) {
+        self.baseRevision = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_baseRevision(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.baseRevision.is_none() {
+            self.baseRevision.set_default();
+        }
+        self.baseRevision.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_baseRevision(&mut self) -> ::std::vec::Vec<u8> {
+        self.baseRevision.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    }
+
+    // optional bytes hintRevision = 9;
+
+
+    pub fn get_hintRevision(&self) -> &[u8] {
+        match self.hintRevision.as_ref() {
+            Some(v) => &v,
+            None => &[],
+        }
+    }
+    pub fn clear_hintRevision(&mut self) {
+        self.hintRevision.clear();
+    }
+
+    pub fn has_hintRevision(&self) -> bool {
+        self.hintRevision.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_hintRevision(&mut self, v: ::std::vec::Vec<u8>) {
+        self.hintRevision = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_hintRevision(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.hintRevision.is_none() {
+            self.hintRevision.set_default();
+        }
+        self.hintRevision.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_hintRevision(&mut self) -> ::std::vec::Vec<u8> {
+        self.hintRevision.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    }
+
+    // optional bool wantNothingIfUpToDate = 10;
+
+
+    pub fn get_wantNothingIfUpToDate(&self) -> bool {
+        self.wantNothingIfUpToDate.unwrap_or(false)
+    }
+    pub fn clear_wantNothingIfUpToDate(&mut self) {
+        self.wantNothingIfUpToDate = ::std::option::Option::None;
+    }
+
+    pub fn has_wantNothingIfUpToDate(&self) -> bool {
+        self.wantNothingIfUpToDate.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_wantNothingIfUpToDate(&mut self, v: bool) {
+        self.wantNothingIfUpToDate = ::std::option::Option::Some(v);
+    }
+
+    // optional bool wantResolveAction = 12;
+
+
+    pub fn get_wantResolveAction(&self) -> bool {
+        self.wantResolveAction.unwrap_or(false)
+    }
+    pub fn clear_wantResolveAction(&mut self) {
+        self.wantResolveAction = ::std::option::Option::None;
+    }
+
+    pub fn has_wantResolveAction(&self) -> bool {
+        self.wantResolveAction.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_wantResolveAction(&mut self, v: bool) {
+        self.wantResolveAction = ::std::option::Option::Some(v);
+    }
+
+    // repeated .ClientIssue issues = 13;
+
+
+    pub fn get_issues(&self) -> &[super::playlist4issues::ClientIssue] {
+        &self.issues
+    }
+    pub fn clear_issues(&mut self) {
+        self.issues.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_issues(&mut self, v: ::protobuf::RepeatedField<super::playlist4issues::ClientIssue>) {
+        self.issues = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_issues(&mut self) -> &mut ::protobuf::RepeatedField<super::playlist4issues::ClientIssue> {
+        &mut self.issues
+    }
+
+    // Take field
+    pub fn take_issues(&mut self) -> ::protobuf::RepeatedField<super::playlist4issues::ClientIssue> {
+        ::std::mem::replace(&mut self.issues, ::protobuf::RepeatedField::new())
+    }
+
+    // repeated .ClientResolveAction resolveAction = 14;
+
+
+    pub fn get_resolveAction(&self) -> &[super::playlist4issues::ClientResolveAction] {
+        &self.resolveAction
+    }
+    pub fn clear_resolveAction(&mut self) {
+        self.resolveAction.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_resolveAction(&mut self, v: ::protobuf::RepeatedField<super::playlist4issues::ClientResolveAction>) {
+        self.resolveAction = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_resolveAction(&mut self) -> &mut ::protobuf::RepeatedField<super::playlist4issues::ClientResolveAction> {
+        &mut self.resolveAction
+    }
+
+    // Take field
+    pub fn take_resolveAction(&mut self) -> ::protobuf::RepeatedField<super::playlist4issues::ClientResolveAction> {
+        ::std::mem::replace(&mut self.resolveAction, ::protobuf::RepeatedField::new())
+    }
+}
+
+impl ::protobuf::Message for ListContentSelection {
+    fn is_initialized(&self) -> bool {
+        for v in &self.contentRange {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.issues {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.resolveAction {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.wantRevision = ::std::option::Option::Some(tmp);
+                },
+                2 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.wantLength = ::std::option::Option::Some(tmp);
+                },
+                3 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.wantAttributes = ::std::option::Option::Some(tmp);
+                },
+                4 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.wantChecksum = ::std::option::Option::Some(tmp);
+                },
+                5 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.wantContent = ::std::option::Option::Some(tmp);
+                },
+                6 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.contentRange)?;
+                },
+                7 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.wantDiff = ::std::option::Option::Some(tmp);
+                },
+                8 => {
+                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.baseRevision)?;
+                },
+                9 => {
+                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.hintRevision)?;
+                },
+                10 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.wantNothingIfUpToDate = ::std::option::Option::Some(tmp);
+                },
+                12 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.wantResolveAction = ::std::option::Option::Some(tmp);
+                },
+                13 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.issues)?;
+                },
+                14 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.resolveAction)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(v) = self.wantRevision {
+            my_size += 2;
+        }
+        if let Some(v) = self.wantLength {
+            my_size += 2;
+        }
+        if let Some(v) = self.wantAttributes {
+            my_size += 2;
+        }
+        if let Some(v) = self.wantChecksum {
+            my_size += 2;
+        }
+        if let Some(v) = self.wantContent {
+            my_size += 2;
+        }
+        if let Some(ref v) = self.contentRange.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(v) = self.wantDiff {
+            my_size += 2;
+        }
+        if let Some(ref v) = self.baseRevision.as_ref() {
+            my_size += ::protobuf::rt::bytes_size(8, &v);
+        }
+        if let Some(ref v) = self.hintRevision.as_ref() {
+            my_size += ::protobuf::rt::bytes_size(9, &v);
+        }
+        if let Some(v) = self.wantNothingIfUpToDate {
+            my_size += 2;
+        }
+        if let Some(v) = self.wantResolveAction {
+            my_size += 2;
+        }
+        for value in &self.issues {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        for value in &self.resolveAction {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(v) = self.wantRevision {
+            os.write_bool(1, v)?;
+        }
+        if let Some(v) = self.wantLength {
+            os.write_bool(2, v)?;
+        }
+        if let Some(v) = self.wantAttributes {
+            os.write_bool(3, v)?;
+        }
+        if let Some(v) = self.wantChecksum {
+            os.write_bool(4, v)?;
+        }
+        if let Some(v) = self.wantContent {
+            os.write_bool(5, v)?;
+        }
+        if let Some(ref v) = self.contentRange.as_ref() {
+            os.write_tag(6, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(v) = self.wantDiff {
+            os.write_bool(7, v)?;
+        }
+        if let Some(ref v) = self.baseRevision.as_ref() {
+            os.write_bytes(8, &v)?;
+        }
+        if let Some(ref v) = self.hintRevision.as_ref() {
+            os.write_bytes(9, &v)?;
+        }
+        if let Some(v) = self.wantNothingIfUpToDate {
+            os.write_bool(10, v)?;
+        }
+        if let Some(v) = self.wantResolveAction {
+            os.write_bool(12, v)?;
+        }
+        for v in &self.issues {
+            os.write_tag(13, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        for v in &self.resolveAction {
+            os.write_tag(14, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ListContentSelection {
+        ListContentSelection::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "wantRevision",
+                    |m: &ListContentSelection| { &m.wantRevision },
+                    |m: &mut ListContentSelection| { &mut m.wantRevision },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "wantLength",
+                    |m: &ListContentSelection| { &m.wantLength },
+                    |m: &mut ListContentSelection| { &mut m.wantLength },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "wantAttributes",
+                    |m: &ListContentSelection| { &m.wantAttributes },
+                    |m: &mut ListContentSelection| { &mut m.wantAttributes },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "wantChecksum",
+                    |m: &ListContentSelection| { &m.wantChecksum },
+                    |m: &mut ListContentSelection| { &mut m.wantChecksum },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "wantContent",
+                    |m: &ListContentSelection| { &m.wantContent },
+                    |m: &mut ListContentSelection| { &mut m.wantContent },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ContentRange>>(
+                    "contentRange",
+                    |m: &ListContentSelection| { &m.contentRange },
+                    |m: &mut ListContentSelection| { &mut m.contentRange },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "wantDiff",
+                    |m: &ListContentSelection| { &m.wantDiff },
+                    |m: &mut ListContentSelection| { &mut m.wantDiff },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                    "baseRevision",
+                    |m: &ListContentSelection| { &m.baseRevision },
+                    |m: &mut ListContentSelection| { &mut m.baseRevision },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                    "hintRevision",
+                    |m: &ListContentSelection| { &m.hintRevision },
+                    |m: &mut ListContentSelection| { &mut m.hintRevision },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "wantNothingIfUpToDate",
+                    |m: &ListContentSelection| { &m.wantNothingIfUpToDate },
+                    |m: &mut ListContentSelection| { &mut m.wantNothingIfUpToDate },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "wantResolveAction",
+                    |m: &ListContentSelection| { &m.wantResolveAction },
+                    |m: &mut ListContentSelection| { &mut m.wantResolveAction },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4issues::ClientIssue>>(
+                    "issues",
+                    |m: &ListContentSelection| { &m.issues },
+                    |m: &mut ListContentSelection| { &mut m.issues },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4issues::ClientResolveAction>>(
+                    "resolveAction",
+                    |m: &ListContentSelection| { &m.resolveAction },
+                    |m: &mut ListContentSelection| { &mut m.resolveAction },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<ListContentSelection>(
+                    "ListContentSelection",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static ListContentSelection {
+        static mut instance: ::protobuf::lazy::Lazy<ListContentSelection> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ListContentSelection,
+        };
+        unsafe {
+            instance.get(ListContentSelection::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for ListContentSelection {
+    fn clear(&mut self) {
+        self.wantRevision = ::std::option::Option::None;
+        self.wantLength = ::std::option::Option::None;
+        self.wantAttributes = ::std::option::Option::None;
+        self.wantChecksum = ::std::option::Option::None;
+        self.wantContent = ::std::option::Option::None;
+        self.contentRange.clear();
+        self.wantDiff = ::std::option::Option::None;
+        self.baseRevision.clear();
+        self.hintRevision.clear();
+        self.wantNothingIfUpToDate = ::std::option::Option::None;
+        self.wantResolveAction = ::std::option::Option::None;
+        self.issues.clear();
+        self.resolveAction.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ListContentSelection {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ListContentSelection {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+static file_descriptor_proto_data: &'static [u8] = b"\
+    \n\x16playlist4content.proto\x12\0\">\n\x04Item\x12\r\n\x03uri\x18\x01\
+    \x20\x01(\tB\0\x12%\n\nattributes\x18\x02\x20\x01(\x0b2\x0f.ItemAttribut\
+    esB\0:\0\"I\n\tListItems\x12\r\n\x03pos\x18\x01\x20\x01(\x05B\0\x12\x13\
+    \n\ttruncated\x18\x02\x20\x01(\x08B\0\x12\x16\n\x05items\x18\x03\x20\x03\
+    (\x0b2\x05.ItemB\0:\0\"1\n\x0cContentRange\x12\r\n\x03pos\x18\x01\x20\
+    \x01(\x05B\0\x12\x10\n\x06length\x18\x02\x20\x01(\x05B\0:\0\"\x87\x03\n\
+    \x14ListContentSelection\x12\x16\n\x0cwantRevision\x18\x01\x20\x01(\x08B\
+    \0\x12\x14\n\nwantLength\x18\x02\x20\x01(\x08B\0\x12\x18\n\x0ewantAttrib\
+    utes\x18\x03\x20\x01(\x08B\0\x12\x16\n\x0cwantChecksum\x18\x04\x20\x01(\
+    \x08B\0\x12\x15\n\x0bwantContent\x18\x05\x20\x01(\x08B\0\x12%\n\x0cconte\
+    ntRange\x18\x06\x20\x01(\x0b2\r.ContentRangeB\0\x12\x12\n\x08wantDiff\
+    \x18\x07\x20\x01(\x08B\0\x12\x16\n\x0cbaseRevision\x18\x08\x20\x01(\x0cB\
+    \0\x12\x16\n\x0chintRevision\x18\t\x20\x01(\x0cB\0\x12\x1f\n\x15wantNoth\
+    ingIfUpToDate\x18\n\x20\x01(\x08B\0\x12\x1b\n\x11wantResolveAction\x18\
+    \x0c\x20\x01(\x08B\0\x12\x1e\n\x06issues\x18\r\x20\x03(\x0b2\x0c.ClientI\
+    ssueB\0\x12-\n\rresolveAction\x18\x0e\x20\x03(\x0b2\x14.ClientResolveAct\
+    ionB\0:\0B\0b\x06proto2\
+";
+
+static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy {
+    lock: ::protobuf::lazy::ONCE_INIT,
+    ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto,
+};
+
+fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
+    ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()
+}
+
+pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
+    unsafe {
+        file_descriptor_proto_lazy.get(|| {
+            parse_descriptor_proto()
+        })
+    }
+}

+ 761 - 0
protocol/src/playlist4issues.rs

@@ -0,0 +1,761 @@
+// This file is generated by rust-protobuf 2.7.0. Do not edit
+// @generated
+
+// https://github.com/Manishearth/rust-clippy/issues/702
+#![allow(unknown_lints)]
+#![allow(clippy::all)]
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+
+#![allow(box_pointers)]
+#![allow(dead_code)]
+#![allow(missing_docs)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![allow(trivial_casts)]
+#![allow(unsafe_code)]
+#![allow(unused_imports)]
+#![allow(unused_results)]
+//! Generated file from `playlist4issues.proto`
+
+use protobuf::Message as Message_imported_for_functions;
+use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
+
+/// Generated files are compatible only with the same version
+/// of protobuf runtime.
+const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_7_0;
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ClientIssue {
+    // message fields
+    level: ::std::option::Option<ClientIssue_Level>,
+    code: ::std::option::Option<ClientIssue_Code>,
+    repeatCount: ::std::option::Option<i32>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ClientIssue {
+    fn default() -> &'a ClientIssue {
+        <ClientIssue as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ClientIssue {
+    pub fn new() -> ClientIssue {
+        ::std::default::Default::default()
+    }
+
+    // optional .ClientIssue.Level level = 1;
+
+
+    pub fn get_level(&self) -> ClientIssue_Level {
+        self.level.unwrap_or(ClientIssue_Level::LEVEL_UNKNOWN)
+    }
+    pub fn clear_level(&mut self) {
+        self.level = ::std::option::Option::None;
+    }
+
+    pub fn has_level(&self) -> bool {
+        self.level.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_level(&mut self, v: ClientIssue_Level) {
+        self.level = ::std::option::Option::Some(v);
+    }
+
+    // optional .ClientIssue.Code code = 2;
+
+
+    pub fn get_code(&self) -> ClientIssue_Code {
+        self.code.unwrap_or(ClientIssue_Code::CODE_UNKNOWN)
+    }
+    pub fn clear_code(&mut self) {
+        self.code = ::std::option::Option::None;
+    }
+
+    pub fn has_code(&self) -> bool {
+        self.code.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_code(&mut self, v: ClientIssue_Code) {
+        self.code = ::std::option::Option::Some(v);
+    }
+
+    // optional int32 repeatCount = 3;
+
+
+    pub fn get_repeatCount(&self) -> i32 {
+        self.repeatCount.unwrap_or(0)
+    }
+    pub fn clear_repeatCount(&mut self) {
+        self.repeatCount = ::std::option::Option::None;
+    }
+
+    pub fn has_repeatCount(&self) -> bool {
+        self.repeatCount.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_repeatCount(&mut self, v: i32) {
+        self.repeatCount = ::std::option::Option::Some(v);
+    }
+}
+
+impl ::protobuf::Message for ClientIssue {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_proto2_enum_with_unknown_fields_into(wire_type, is, &mut self.level, 1, &mut self.unknown_fields)?
+                },
+                2 => {
+                    ::protobuf::rt::read_proto2_enum_with_unknown_fields_into(wire_type, is, &mut self.code, 2, &mut self.unknown_fields)?
+                },
+                3 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.repeatCount = ::std::option::Option::Some(tmp);
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(v) = self.level {
+            my_size += ::protobuf::rt::enum_size(1, v);
+        }
+        if let Some(v) = self.code {
+            my_size += ::protobuf::rt::enum_size(2, v);
+        }
+        if let Some(v) = self.repeatCount {
+            my_size += ::protobuf::rt::value_size(3, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(v) = self.level {
+            os.write_enum(1, v.value())?;
+        }
+        if let Some(v) = self.code {
+            os.write_enum(2, v.value())?;
+        }
+        if let Some(v) = self.repeatCount {
+            os.write_int32(3, v)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ClientIssue {
+        ClientIssue::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ClientIssue_Level>>(
+                    "level",
+                    |m: &ClientIssue| { &m.level },
+                    |m: &mut ClientIssue| { &mut m.level },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ClientIssue_Code>>(
+                    "code",
+                    |m: &ClientIssue| { &m.code },
+                    |m: &mut ClientIssue| { &mut m.code },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "repeatCount",
+                    |m: &ClientIssue| { &m.repeatCount },
+                    |m: &mut ClientIssue| { &mut m.repeatCount },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<ClientIssue>(
+                    "ClientIssue",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static ClientIssue {
+        static mut instance: ::protobuf::lazy::Lazy<ClientIssue> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ClientIssue,
+        };
+        unsafe {
+            instance.get(ClientIssue::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for ClientIssue {
+    fn clear(&mut self) {
+        self.level = ::std::option::Option::None;
+        self.code = ::std::option::Option::None;
+        self.repeatCount = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ClientIssue {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ClientIssue {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(Clone,PartialEq,Eq,Debug,Hash)]
+pub enum ClientIssue_Level {
+    LEVEL_UNKNOWN = 0,
+    LEVEL_DEBUG = 1,
+    LEVEL_INFO = 2,
+    LEVEL_NOTICE = 3,
+    LEVEL_WARNING = 4,
+    LEVEL_ERROR = 5,
+}
+
+impl ::protobuf::ProtobufEnum for ClientIssue_Level {
+    fn value(&self) -> i32 {
+        *self as i32
+    }
+
+    fn from_i32(value: i32) -> ::std::option::Option<ClientIssue_Level> {
+        match value {
+            0 => ::std::option::Option::Some(ClientIssue_Level::LEVEL_UNKNOWN),
+            1 => ::std::option::Option::Some(ClientIssue_Level::LEVEL_DEBUG),
+            2 => ::std::option::Option::Some(ClientIssue_Level::LEVEL_INFO),
+            3 => ::std::option::Option::Some(ClientIssue_Level::LEVEL_NOTICE),
+            4 => ::std::option::Option::Some(ClientIssue_Level::LEVEL_WARNING),
+            5 => ::std::option::Option::Some(ClientIssue_Level::LEVEL_ERROR),
+            _ => ::std::option::Option::None
+        }
+    }
+
+    fn values() -> &'static [Self] {
+        static values: &'static [ClientIssue_Level] = &[
+            ClientIssue_Level::LEVEL_UNKNOWN,
+            ClientIssue_Level::LEVEL_DEBUG,
+            ClientIssue_Level::LEVEL_INFO,
+            ClientIssue_Level::LEVEL_NOTICE,
+            ClientIssue_Level::LEVEL_WARNING,
+            ClientIssue_Level::LEVEL_ERROR,
+        ];
+        values
+    }
+
+    fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::EnumDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                ::protobuf::reflect::EnumDescriptor::new("ClientIssue_Level", file_descriptor_proto())
+            })
+        }
+    }
+}
+
+impl ::std::marker::Copy for ClientIssue_Level {
+}
+
+impl ::std::default::Default for ClientIssue_Level {
+    fn default() -> Self {
+        ClientIssue_Level::LEVEL_UNKNOWN
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ClientIssue_Level {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor())
+    }
+}
+
+#[derive(Clone,PartialEq,Eq,Debug,Hash)]
+pub enum ClientIssue_Code {
+    CODE_UNKNOWN = 0,
+    CODE_INDEX_OUT_OF_BOUNDS = 1,
+    CODE_VERSION_MISMATCH = 2,
+    CODE_CACHED_CHANGE = 3,
+    CODE_OFFLINE_CHANGE = 4,
+    CODE_CONCURRENT_CHANGE = 5,
+}
+
+impl ::protobuf::ProtobufEnum for ClientIssue_Code {
+    fn value(&self) -> i32 {
+        *self as i32
+    }
+
+    fn from_i32(value: i32) -> ::std::option::Option<ClientIssue_Code> {
+        match value {
+            0 => ::std::option::Option::Some(ClientIssue_Code::CODE_UNKNOWN),
+            1 => ::std::option::Option::Some(ClientIssue_Code::CODE_INDEX_OUT_OF_BOUNDS),
+            2 => ::std::option::Option::Some(ClientIssue_Code::CODE_VERSION_MISMATCH),
+            3 => ::std::option::Option::Some(ClientIssue_Code::CODE_CACHED_CHANGE),
+            4 => ::std::option::Option::Some(ClientIssue_Code::CODE_OFFLINE_CHANGE),
+            5 => ::std::option::Option::Some(ClientIssue_Code::CODE_CONCURRENT_CHANGE),
+            _ => ::std::option::Option::None
+        }
+    }
+
+    fn values() -> &'static [Self] {
+        static values: &'static [ClientIssue_Code] = &[
+            ClientIssue_Code::CODE_UNKNOWN,
+            ClientIssue_Code::CODE_INDEX_OUT_OF_BOUNDS,
+            ClientIssue_Code::CODE_VERSION_MISMATCH,
+            ClientIssue_Code::CODE_CACHED_CHANGE,
+            ClientIssue_Code::CODE_OFFLINE_CHANGE,
+            ClientIssue_Code::CODE_CONCURRENT_CHANGE,
+        ];
+        values
+    }
+
+    fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::EnumDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                ::protobuf::reflect::EnumDescriptor::new("ClientIssue_Code", file_descriptor_proto())
+            })
+        }
+    }
+}
+
+impl ::std::marker::Copy for ClientIssue_Code {
+}
+
+impl ::std::default::Default for ClientIssue_Code {
+    fn default() -> Self {
+        ClientIssue_Code::CODE_UNKNOWN
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ClientIssue_Code {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor())
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ClientResolveAction {
+    // message fields
+    code: ::std::option::Option<ClientResolveAction_Code>,
+    initiator: ::std::option::Option<ClientResolveAction_Initiator>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ClientResolveAction {
+    fn default() -> &'a ClientResolveAction {
+        <ClientResolveAction as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ClientResolveAction {
+    pub fn new() -> ClientResolveAction {
+        ::std::default::Default::default()
+    }
+
+    // optional .ClientResolveAction.Code code = 1;
+
+
+    pub fn get_code(&self) -> ClientResolveAction_Code {
+        self.code.unwrap_or(ClientResolveAction_Code::CODE_UNKNOWN)
+    }
+    pub fn clear_code(&mut self) {
+        self.code = ::std::option::Option::None;
+    }
+
+    pub fn has_code(&self) -> bool {
+        self.code.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_code(&mut self, v: ClientResolveAction_Code) {
+        self.code = ::std::option::Option::Some(v);
+    }
+
+    // optional .ClientResolveAction.Initiator initiator = 2;
+
+
+    pub fn get_initiator(&self) -> ClientResolveAction_Initiator {
+        self.initiator.unwrap_or(ClientResolveAction_Initiator::INITIATOR_UNKNOWN)
+    }
+    pub fn clear_initiator(&mut self) {
+        self.initiator = ::std::option::Option::None;
+    }
+
+    pub fn has_initiator(&self) -> bool {
+        self.initiator.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_initiator(&mut self, v: ClientResolveAction_Initiator) {
+        self.initiator = ::std::option::Option::Some(v);
+    }
+}
+
+impl ::protobuf::Message for ClientResolveAction {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_proto2_enum_with_unknown_fields_into(wire_type, is, &mut self.code, 1, &mut self.unknown_fields)?
+                },
+                2 => {
+                    ::protobuf::rt::read_proto2_enum_with_unknown_fields_into(wire_type, is, &mut self.initiator, 2, &mut self.unknown_fields)?
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(v) = self.code {
+            my_size += ::protobuf::rt::enum_size(1, v);
+        }
+        if let Some(v) = self.initiator {
+            my_size += ::protobuf::rt::enum_size(2, v);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(v) = self.code {
+            os.write_enum(1, v.value())?;
+        }
+        if let Some(v) = self.initiator {
+            os.write_enum(2, v.value())?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ClientResolveAction {
+        ClientResolveAction::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ClientResolveAction_Code>>(
+                    "code",
+                    |m: &ClientResolveAction| { &m.code },
+                    |m: &mut ClientResolveAction| { &mut m.code },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ClientResolveAction_Initiator>>(
+                    "initiator",
+                    |m: &ClientResolveAction| { &m.initiator },
+                    |m: &mut ClientResolveAction| { &mut m.initiator },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<ClientResolveAction>(
+                    "ClientResolveAction",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static ClientResolveAction {
+        static mut instance: ::protobuf::lazy::Lazy<ClientResolveAction> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ClientResolveAction,
+        };
+        unsafe {
+            instance.get(ClientResolveAction::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for ClientResolveAction {
+    fn clear(&mut self) {
+        self.code = ::std::option::Option::None;
+        self.initiator = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ClientResolveAction {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ClientResolveAction {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(Clone,PartialEq,Eq,Debug,Hash)]
+pub enum ClientResolveAction_Code {
+    CODE_UNKNOWN = 0,
+    CODE_NO_ACTION = 1,
+    CODE_RETRY = 2,
+    CODE_RELOAD = 3,
+    CODE_DISCARD_LOCAL_CHANGES = 4,
+    CODE_SEND_DUMP = 5,
+    CODE_DISPLAY_ERROR_MESSAGE = 6,
+}
+
+impl ::protobuf::ProtobufEnum for ClientResolveAction_Code {
+    fn value(&self) -> i32 {
+        *self as i32
+    }
+
+    fn from_i32(value: i32) -> ::std::option::Option<ClientResolveAction_Code> {
+        match value {
+            0 => ::std::option::Option::Some(ClientResolveAction_Code::CODE_UNKNOWN),
+            1 => ::std::option::Option::Some(ClientResolveAction_Code::CODE_NO_ACTION),
+            2 => ::std::option::Option::Some(ClientResolveAction_Code::CODE_RETRY),
+            3 => ::std::option::Option::Some(ClientResolveAction_Code::CODE_RELOAD),
+            4 => ::std::option::Option::Some(ClientResolveAction_Code::CODE_DISCARD_LOCAL_CHANGES),
+            5 => ::std::option::Option::Some(ClientResolveAction_Code::CODE_SEND_DUMP),
+            6 => ::std::option::Option::Some(ClientResolveAction_Code::CODE_DISPLAY_ERROR_MESSAGE),
+            _ => ::std::option::Option::None
+        }
+    }
+
+    fn values() -> &'static [Self] {
+        static values: &'static [ClientResolveAction_Code] = &[
+            ClientResolveAction_Code::CODE_UNKNOWN,
+            ClientResolveAction_Code::CODE_NO_ACTION,
+            ClientResolveAction_Code::CODE_RETRY,
+            ClientResolveAction_Code::CODE_RELOAD,
+            ClientResolveAction_Code::CODE_DISCARD_LOCAL_CHANGES,
+            ClientResolveAction_Code::CODE_SEND_DUMP,
+            ClientResolveAction_Code::CODE_DISPLAY_ERROR_MESSAGE,
+        ];
+        values
+    }
+
+    fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::EnumDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                ::protobuf::reflect::EnumDescriptor::new("ClientResolveAction_Code", file_descriptor_proto())
+            })
+        }
+    }
+}
+
+impl ::std::marker::Copy for ClientResolveAction_Code {
+}
+
+impl ::std::default::Default for ClientResolveAction_Code {
+    fn default() -> Self {
+        ClientResolveAction_Code::CODE_UNKNOWN
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ClientResolveAction_Code {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor())
+    }
+}
+
+#[derive(Clone,PartialEq,Eq,Debug,Hash)]
+pub enum ClientResolveAction_Initiator {
+    INITIATOR_UNKNOWN = 0,
+    INITIATOR_SERVER = 1,
+    INITIATOR_CLIENT = 2,
+}
+
+impl ::protobuf::ProtobufEnum for ClientResolveAction_Initiator {
+    fn value(&self) -> i32 {
+        *self as i32
+    }
+
+    fn from_i32(value: i32) -> ::std::option::Option<ClientResolveAction_Initiator> {
+        match value {
+            0 => ::std::option::Option::Some(ClientResolveAction_Initiator::INITIATOR_UNKNOWN),
+            1 => ::std::option::Option::Some(ClientResolveAction_Initiator::INITIATOR_SERVER),
+            2 => ::std::option::Option::Some(ClientResolveAction_Initiator::INITIATOR_CLIENT),
+            _ => ::std::option::Option::None
+        }
+    }
+
+    fn values() -> &'static [Self] {
+        static values: &'static [ClientResolveAction_Initiator] = &[
+            ClientResolveAction_Initiator::INITIATOR_UNKNOWN,
+            ClientResolveAction_Initiator::INITIATOR_SERVER,
+            ClientResolveAction_Initiator::INITIATOR_CLIENT,
+        ];
+        values
+    }
+
+    fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::EnumDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                ::protobuf::reflect::EnumDescriptor::new("ClientResolveAction_Initiator", file_descriptor_proto())
+            })
+        }
+    }
+}
+
+impl ::std::marker::Copy for ClientResolveAction_Initiator {
+}
+
+impl ::std::default::Default for ClientResolveAction_Initiator {
+    fn default() -> Self {
+        ClientResolveAction_Initiator::INITIATOR_UNKNOWN
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ClientResolveAction_Initiator {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor())
+    }
+}
+
+static file_descriptor_proto_data: &'static [u8] = b"\
+    \n\x15playlist4issues.proto\x12\0\"\x86\x03\n\x0bClientIssue\x12#\n\x05l\
+    evel\x18\x01\x20\x01(\x0e2\x12.ClientIssue.LevelB\0\x12!\n\x04code\x18\
+    \x02\x20\x01(\x0e2\x11.ClientIssue.CodeB\0\x12\x15\n\x0brepeatCount\x18\
+    \x03\x20\x01(\x05B\0\"s\n\x05Level\x12\x11\n\rLEVEL_UNKNOWN\x10\0\x12\
+    \x0f\n\x0bLEVEL_DEBUG\x10\x01\x12\x0e\n\nLEVEL_INFO\x10\x02\x12\x10\n\
+    \x0cLEVEL_NOTICE\x10\x03\x12\x11\n\rLEVEL_WARNING\x10\x04\x12\x0f\n\x0bL\
+    EVEL_ERROR\x10\x05\x1a\0\"\xa0\x01\n\x04Code\x12\x10\n\x0cCODE_UNKNOWN\
+    \x10\0\x12\x1c\n\x18CODE_INDEX_OUT_OF_BOUNDS\x10\x01\x12\x19\n\x15CODE_V\
+    ERSION_MISMATCH\x10\x02\x12\x16\n\x12CODE_CACHED_CHANGE\x10\x03\x12\x17\
+    \n\x13CODE_OFFLINE_CHANGE\x10\x04\x12\x1a\n\x16CODE_CONCURRENT_CHANGE\
+    \x10\x05\x1a\0:\0\"\xef\x02\n\x13ClientResolveAction\x12)\n\x04code\x18\
+    \x01\x20\x01(\x0e2\x19.ClientResolveAction.CodeB\0\x123\n\tinitiator\x18\
+    \x02\x20\x01(\x0e2\x1e.ClientResolveAction.InitiatorB\0\"\xa3\x01\n\x04C\
+    ode\x12\x10\n\x0cCODE_UNKNOWN\x10\0\x12\x12\n\x0eCODE_NO_ACTION\x10\x01\
+    \x12\x0e\n\nCODE_RETRY\x10\x02\x12\x0f\n\x0bCODE_RELOAD\x10\x03\x12\x1e\
+    \n\x1aCODE_DISCARD_LOCAL_CHANGES\x10\x04\x12\x12\n\x0eCODE_SEND_DUMP\x10\
+    \x05\x12\x1e\n\x1aCODE_DISPLAY_ERROR_MESSAGE\x10\x06\x1a\0\"P\n\tInitiat\
+    or\x12\x15\n\x11INITIATOR_UNKNOWN\x10\0\x12\x14\n\x10INITIATOR_SERVER\
+    \x10\x01\x12\x14\n\x10INITIATOR_CLIENT\x10\x02\x1a\0:\0B\0b\x06proto2\
+";
+
+static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy {
+    lock: ::protobuf::lazy::ONCE_INIT,
+    ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto,
+};
+
+fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
+    ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()
+}
+
+pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
+    unsafe {
+        file_descriptor_proto_lazy.get(|| {
+            parse_descriptor_proto()
+        })
+    }
+}

+ 2074 - 0
protocol/src/playlist4meta.rs

@@ -0,0 +1,2074 @@
+// This file is generated by rust-protobuf 2.7.0. Do not edit
+// @generated
+
+// https://github.com/Manishearth/rust-clippy/issues/702
+#![allow(unknown_lints)]
+#![allow(clippy::all)]
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+
+#![allow(box_pointers)]
+#![allow(dead_code)]
+#![allow(missing_docs)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![allow(trivial_casts)]
+#![allow(unsafe_code)]
+#![allow(unused_imports)]
+#![allow(unused_results)]
+//! Generated file from `playlist4meta.proto`
+
+use protobuf::Message as Message_imported_for_functions;
+use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
+
+/// Generated files are compatible only with the same version
+/// of protobuf runtime.
+const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_7_0;
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ListChecksum {
+    // message fields
+    version: ::std::option::Option<i32>,
+    sha1: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ListChecksum {
+    fn default() -> &'a ListChecksum {
+        <ListChecksum as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ListChecksum {
+    pub fn new() -> ListChecksum {
+        ::std::default::Default::default()
+    }
+
+    // optional int32 version = 1;
+
+
+    pub fn get_version(&self) -> i32 {
+        self.version.unwrap_or(0)
+    }
+    pub fn clear_version(&mut self) {
+        self.version = ::std::option::Option::None;
+    }
+
+    pub fn has_version(&self) -> bool {
+        self.version.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_version(&mut self, v: i32) {
+        self.version = ::std::option::Option::Some(v);
+    }
+
+    // optional bytes sha1 = 4;
+
+
+    pub fn get_sha1(&self) -> &[u8] {
+        match self.sha1.as_ref() {
+            Some(v) => &v,
+            None => &[],
+        }
+    }
+    pub fn clear_sha1(&mut self) {
+        self.sha1.clear();
+    }
+
+    pub fn has_sha1(&self) -> bool {
+        self.sha1.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_sha1(&mut self, v: ::std::vec::Vec<u8>) {
+        self.sha1 = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_sha1(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.sha1.is_none() {
+            self.sha1.set_default();
+        }
+        self.sha1.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_sha1(&mut self) -> ::std::vec::Vec<u8> {
+        self.sha1.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    }
+}
+
+impl ::protobuf::Message for ListChecksum {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.version = ::std::option::Option::Some(tmp);
+                },
+                4 => {
+                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.sha1)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(v) = self.version {
+            my_size += ::protobuf::rt::value_size(1, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(ref v) = self.sha1.as_ref() {
+            my_size += ::protobuf::rt::bytes_size(4, &v);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(v) = self.version {
+            os.write_int32(1, v)?;
+        }
+        if let Some(ref v) = self.sha1.as_ref() {
+            os.write_bytes(4, &v)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ListChecksum {
+        ListChecksum::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "version",
+                    |m: &ListChecksum| { &m.version },
+                    |m: &mut ListChecksum| { &mut m.version },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                    "sha1",
+                    |m: &ListChecksum| { &m.sha1 },
+                    |m: &mut ListChecksum| { &mut m.sha1 },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<ListChecksum>(
+                    "ListChecksum",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static ListChecksum {
+        static mut instance: ::protobuf::lazy::Lazy<ListChecksum> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ListChecksum,
+        };
+        unsafe {
+            instance.get(ListChecksum::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for ListChecksum {
+    fn clear(&mut self) {
+        self.version = ::std::option::Option::None;
+        self.sha1.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ListChecksum {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ListChecksum {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct DownloadFormat {
+    // message fields
+    codec: ::std::option::Option<DownloadFormat_Codec>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a DownloadFormat {
+    fn default() -> &'a DownloadFormat {
+        <DownloadFormat as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl DownloadFormat {
+    pub fn new() -> DownloadFormat {
+        ::std::default::Default::default()
+    }
+
+    // optional .DownloadFormat.Codec codec = 1;
+
+
+    pub fn get_codec(&self) -> DownloadFormat_Codec {
+        self.codec.unwrap_or(DownloadFormat_Codec::CODEC_UNKNOWN)
+    }
+    pub fn clear_codec(&mut self) {
+        self.codec = ::std::option::Option::None;
+    }
+
+    pub fn has_codec(&self) -> bool {
+        self.codec.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_codec(&mut self, v: DownloadFormat_Codec) {
+        self.codec = ::std::option::Option::Some(v);
+    }
+}
+
+impl ::protobuf::Message for DownloadFormat {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_proto2_enum_with_unknown_fields_into(wire_type, is, &mut self.codec, 1, &mut self.unknown_fields)?
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(v) = self.codec {
+            my_size += ::protobuf::rt::enum_size(1, v);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(v) = self.codec {
+            os.write_enum(1, v.value())?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> DownloadFormat {
+        DownloadFormat::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum<DownloadFormat_Codec>>(
+                    "codec",
+                    |m: &DownloadFormat| { &m.codec },
+                    |m: &mut DownloadFormat| { &mut m.codec },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<DownloadFormat>(
+                    "DownloadFormat",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static DownloadFormat {
+        static mut instance: ::protobuf::lazy::Lazy<DownloadFormat> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const DownloadFormat,
+        };
+        unsafe {
+            instance.get(DownloadFormat::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for DownloadFormat {
+    fn clear(&mut self) {
+        self.codec = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for DownloadFormat {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for DownloadFormat {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(Clone,PartialEq,Eq,Debug,Hash)]
+pub enum DownloadFormat_Codec {
+    CODEC_UNKNOWN = 0,
+    OGG_VORBIS = 1,
+    FLAC = 2,
+    MPEG_1_LAYER_3 = 3,
+}
+
+impl ::protobuf::ProtobufEnum for DownloadFormat_Codec {
+    fn value(&self) -> i32 {
+        *self as i32
+    }
+
+    fn from_i32(value: i32) -> ::std::option::Option<DownloadFormat_Codec> {
+        match value {
+            0 => ::std::option::Option::Some(DownloadFormat_Codec::CODEC_UNKNOWN),
+            1 => ::std::option::Option::Some(DownloadFormat_Codec::OGG_VORBIS),
+            2 => ::std::option::Option::Some(DownloadFormat_Codec::FLAC),
+            3 => ::std::option::Option::Some(DownloadFormat_Codec::MPEG_1_LAYER_3),
+            _ => ::std::option::Option::None
+        }
+    }
+
+    fn values() -> &'static [Self] {
+        static values: &'static [DownloadFormat_Codec] = &[
+            DownloadFormat_Codec::CODEC_UNKNOWN,
+            DownloadFormat_Codec::OGG_VORBIS,
+            DownloadFormat_Codec::FLAC,
+            DownloadFormat_Codec::MPEG_1_LAYER_3,
+        ];
+        values
+    }
+
+    fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::EnumDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                ::protobuf::reflect::EnumDescriptor::new("DownloadFormat_Codec", file_descriptor_proto())
+            })
+        }
+    }
+}
+
+impl ::std::marker::Copy for DownloadFormat_Codec {
+}
+
+impl ::std::default::Default for DownloadFormat_Codec {
+    fn default() -> Self {
+        DownloadFormat_Codec::CODEC_UNKNOWN
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for DownloadFormat_Codec {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor())
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ListAttributes {
+    // message fields
+    name: ::protobuf::SingularField<::std::string::String>,
+    description: ::protobuf::SingularField<::std::string::String>,
+    picture: ::protobuf::SingularField<::std::vec::Vec<u8>>,
+    collaborative: ::std::option::Option<bool>,
+    pl3_version: ::protobuf::SingularField<::std::string::String>,
+    deleted_by_owner: ::std::option::Option<bool>,
+    restricted_collaborative: ::std::option::Option<bool>,
+    deprecated_client_id: ::std::option::Option<i64>,
+    public_starred: ::std::option::Option<bool>,
+    client_id: ::protobuf::SingularField<::std::string::String>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ListAttributes {
+    fn default() -> &'a ListAttributes {
+        <ListAttributes as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ListAttributes {
+    pub fn new() -> ListAttributes {
+        ::std::default::Default::default()
+    }
+
+    // optional string name = 1;
+
+
+    pub fn get_name(&self) -> &str {
+        match self.name.as_ref() {
+            Some(v) => &v,
+            None => "",
+        }
+    }
+    pub fn clear_name(&mut self) {
+        self.name.clear();
+    }
+
+    pub fn has_name(&self) -> bool {
+        self.name.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_name(&mut self, v: ::std::string::String) {
+        self.name = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_name(&mut self) -> &mut ::std::string::String {
+        if self.name.is_none() {
+            self.name.set_default();
+        }
+        self.name.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_name(&mut self) -> ::std::string::String {
+        self.name.take().unwrap_or_else(|| ::std::string::String::new())
+    }
+
+    // optional string description = 2;
+
+
+    pub fn get_description(&self) -> &str {
+        match self.description.as_ref() {
+            Some(v) => &v,
+            None => "",
+        }
+    }
+    pub fn clear_description(&mut self) {
+        self.description.clear();
+    }
+
+    pub fn has_description(&self) -> bool {
+        self.description.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_description(&mut self, v: ::std::string::String) {
+        self.description = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_description(&mut self) -> &mut ::std::string::String {
+        if self.description.is_none() {
+            self.description.set_default();
+        }
+        self.description.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_description(&mut self) -> ::std::string::String {
+        self.description.take().unwrap_or_else(|| ::std::string::String::new())
+    }
+
+    // optional bytes picture = 3;
+
+
+    pub fn get_picture(&self) -> &[u8] {
+        match self.picture.as_ref() {
+            Some(v) => &v,
+            None => &[],
+        }
+    }
+    pub fn clear_picture(&mut self) {
+        self.picture.clear();
+    }
+
+    pub fn has_picture(&self) -> bool {
+        self.picture.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_picture(&mut self, v: ::std::vec::Vec<u8>) {
+        self.picture = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_picture(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.picture.is_none() {
+            self.picture.set_default();
+        }
+        self.picture.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_picture(&mut self) -> ::std::vec::Vec<u8> {
+        self.picture.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    }
+
+    // optional bool collaborative = 4;
+
+
+    pub fn get_collaborative(&self) -> bool {
+        self.collaborative.unwrap_or(false)
+    }
+    pub fn clear_collaborative(&mut self) {
+        self.collaborative = ::std::option::Option::None;
+    }
+
+    pub fn has_collaborative(&self) -> bool {
+        self.collaborative.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_collaborative(&mut self, v: bool) {
+        self.collaborative = ::std::option::Option::Some(v);
+    }
+
+    // optional string pl3_version = 5;
+
+
+    pub fn get_pl3_version(&self) -> &str {
+        match self.pl3_version.as_ref() {
+            Some(v) => &v,
+            None => "",
+        }
+    }
+    pub fn clear_pl3_version(&mut self) {
+        self.pl3_version.clear();
+    }
+
+    pub fn has_pl3_version(&self) -> bool {
+        self.pl3_version.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_pl3_version(&mut self, v: ::std::string::String) {
+        self.pl3_version = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_pl3_version(&mut self) -> &mut ::std::string::String {
+        if self.pl3_version.is_none() {
+            self.pl3_version.set_default();
+        }
+        self.pl3_version.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_pl3_version(&mut self) -> ::std::string::String {
+        self.pl3_version.take().unwrap_or_else(|| ::std::string::String::new())
+    }
+
+    // optional bool deleted_by_owner = 6;
+
+
+    pub fn get_deleted_by_owner(&self) -> bool {
+        self.deleted_by_owner.unwrap_or(false)
+    }
+    pub fn clear_deleted_by_owner(&mut self) {
+        self.deleted_by_owner = ::std::option::Option::None;
+    }
+
+    pub fn has_deleted_by_owner(&self) -> bool {
+        self.deleted_by_owner.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_deleted_by_owner(&mut self, v: bool) {
+        self.deleted_by_owner = ::std::option::Option::Some(v);
+    }
+
+    // optional bool restricted_collaborative = 7;
+
+
+    pub fn get_restricted_collaborative(&self) -> bool {
+        self.restricted_collaborative.unwrap_or(false)
+    }
+    pub fn clear_restricted_collaborative(&mut self) {
+        self.restricted_collaborative = ::std::option::Option::None;
+    }
+
+    pub fn has_restricted_collaborative(&self) -> bool {
+        self.restricted_collaborative.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_restricted_collaborative(&mut self, v: bool) {
+        self.restricted_collaborative = ::std::option::Option::Some(v);
+    }
+
+    // optional int64 deprecated_client_id = 8;
+
+
+    pub fn get_deprecated_client_id(&self) -> i64 {
+        self.deprecated_client_id.unwrap_or(0)
+    }
+    pub fn clear_deprecated_client_id(&mut self) {
+        self.deprecated_client_id = ::std::option::Option::None;
+    }
+
+    pub fn has_deprecated_client_id(&self) -> bool {
+        self.deprecated_client_id.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_deprecated_client_id(&mut self, v: i64) {
+        self.deprecated_client_id = ::std::option::Option::Some(v);
+    }
+
+    // optional bool public_starred = 9;
+
+
+    pub fn get_public_starred(&self) -> bool {
+        self.public_starred.unwrap_or(false)
+    }
+    pub fn clear_public_starred(&mut self) {
+        self.public_starred = ::std::option::Option::None;
+    }
+
+    pub fn has_public_starred(&self) -> bool {
+        self.public_starred.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_public_starred(&mut self, v: bool) {
+        self.public_starred = ::std::option::Option::Some(v);
+    }
+
+    // optional string client_id = 10;
+
+
+    pub fn get_client_id(&self) -> &str {
+        match self.client_id.as_ref() {
+            Some(v) => &v,
+            None => "",
+        }
+    }
+    pub fn clear_client_id(&mut self) {
+        self.client_id.clear();
+    }
+
+    pub fn has_client_id(&self) -> bool {
+        self.client_id.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_client_id(&mut self, v: ::std::string::String) {
+        self.client_id = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_client_id(&mut self) -> &mut ::std::string::String {
+        if self.client_id.is_none() {
+            self.client_id.set_default();
+        }
+        self.client_id.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_client_id(&mut self) -> ::std::string::String {
+        self.client_id.take().unwrap_or_else(|| ::std::string::String::new())
+    }
+}
+
+impl ::protobuf::Message for ListAttributes {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.name)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.description)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.picture)?;
+                },
+                4 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.collaborative = ::std::option::Option::Some(tmp);
+                },
+                5 => {
+                    ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.pl3_version)?;
+                },
+                6 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.deleted_by_owner = ::std::option::Option::Some(tmp);
+                },
+                7 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.restricted_collaborative = ::std::option::Option::Some(tmp);
+                },
+                8 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int64()?;
+                    self.deprecated_client_id = ::std::option::Option::Some(tmp);
+                },
+                9 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.public_starred = ::std::option::Option::Some(tmp);
+                },
+                10 => {
+                    ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.client_id)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.name.as_ref() {
+            my_size += ::protobuf::rt::string_size(1, &v);
+        }
+        if let Some(ref v) = self.description.as_ref() {
+            my_size += ::protobuf::rt::string_size(2, &v);
+        }
+        if let Some(ref v) = self.picture.as_ref() {
+            my_size += ::protobuf::rt::bytes_size(3, &v);
+        }
+        if let Some(v) = self.collaborative {
+            my_size += 2;
+        }
+        if let Some(ref v) = self.pl3_version.as_ref() {
+            my_size += ::protobuf::rt::string_size(5, &v);
+        }
+        if let Some(v) = self.deleted_by_owner {
+            my_size += 2;
+        }
+        if let Some(v) = self.restricted_collaborative {
+            my_size += 2;
+        }
+        if let Some(v) = self.deprecated_client_id {
+            my_size += ::protobuf::rt::value_size(8, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(v) = self.public_starred {
+            my_size += 2;
+        }
+        if let Some(ref v) = self.client_id.as_ref() {
+            my_size += ::protobuf::rt::string_size(10, &v);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.name.as_ref() {
+            os.write_string(1, &v)?;
+        }
+        if let Some(ref v) = self.description.as_ref() {
+            os.write_string(2, &v)?;
+        }
+        if let Some(ref v) = self.picture.as_ref() {
+            os.write_bytes(3, &v)?;
+        }
+        if let Some(v) = self.collaborative {
+            os.write_bool(4, v)?;
+        }
+        if let Some(ref v) = self.pl3_version.as_ref() {
+            os.write_string(5, &v)?;
+        }
+        if let Some(v) = self.deleted_by_owner {
+            os.write_bool(6, v)?;
+        }
+        if let Some(v) = self.restricted_collaborative {
+            os.write_bool(7, v)?;
+        }
+        if let Some(v) = self.deprecated_client_id {
+            os.write_int64(8, v)?;
+        }
+        if let Some(v) = self.public_starred {
+            os.write_bool(9, v)?;
+        }
+        if let Some(ref v) = self.client_id.as_ref() {
+            os.write_string(10, &v)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ListAttributes {
+        ListAttributes::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                    "name",
+                    |m: &ListAttributes| { &m.name },
+                    |m: &mut ListAttributes| { &mut m.name },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                    "description",
+                    |m: &ListAttributes| { &m.description },
+                    |m: &mut ListAttributes| { &mut m.description },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                    "picture",
+                    |m: &ListAttributes| { &m.picture },
+                    |m: &mut ListAttributes| { &mut m.picture },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "collaborative",
+                    |m: &ListAttributes| { &m.collaborative },
+                    |m: &mut ListAttributes| { &mut m.collaborative },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                    "pl3_version",
+                    |m: &ListAttributes| { &m.pl3_version },
+                    |m: &mut ListAttributes| { &mut m.pl3_version },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "deleted_by_owner",
+                    |m: &ListAttributes| { &m.deleted_by_owner },
+                    |m: &mut ListAttributes| { &mut m.deleted_by_owner },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "restricted_collaborative",
+                    |m: &ListAttributes| { &m.restricted_collaborative },
+                    |m: &mut ListAttributes| { &mut m.restricted_collaborative },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt64>(
+                    "deprecated_client_id",
+                    |m: &ListAttributes| { &m.deprecated_client_id },
+                    |m: &mut ListAttributes| { &mut m.deprecated_client_id },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "public_starred",
+                    |m: &ListAttributes| { &m.public_starred },
+                    |m: &mut ListAttributes| { &mut m.public_starred },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                    "client_id",
+                    |m: &ListAttributes| { &m.client_id },
+                    |m: &mut ListAttributes| { &mut m.client_id },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<ListAttributes>(
+                    "ListAttributes",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static ListAttributes {
+        static mut instance: ::protobuf::lazy::Lazy<ListAttributes> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ListAttributes,
+        };
+        unsafe {
+            instance.get(ListAttributes::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for ListAttributes {
+    fn clear(&mut self) {
+        self.name.clear();
+        self.description.clear();
+        self.picture.clear();
+        self.collaborative = ::std::option::Option::None;
+        self.pl3_version.clear();
+        self.deleted_by_owner = ::std::option::Option::None;
+        self.restricted_collaborative = ::std::option::Option::None;
+        self.deprecated_client_id = ::std::option::Option::None;
+        self.public_starred = ::std::option::Option::None;
+        self.client_id.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ListAttributes {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ListAttributes {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ItemAttributes {
+    // message fields
+    added_by: ::protobuf::SingularField<::std::string::String>,
+    timestamp: ::std::option::Option<i64>,
+    message: ::protobuf::SingularField<::std::string::String>,
+    seen: ::std::option::Option<bool>,
+    download_count: ::std::option::Option<i64>,
+    download_format: ::protobuf::SingularPtrField<DownloadFormat>,
+    sevendigital_id: ::protobuf::SingularField<::std::string::String>,
+    sevendigital_left: ::std::option::Option<i64>,
+    seen_at: ::std::option::Option<i64>,
+    public: ::std::option::Option<bool>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ItemAttributes {
+    fn default() -> &'a ItemAttributes {
+        <ItemAttributes as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ItemAttributes {
+    pub fn new() -> ItemAttributes {
+        ::std::default::Default::default()
+    }
+
+    // optional string added_by = 1;
+
+
+    pub fn get_added_by(&self) -> &str {
+        match self.added_by.as_ref() {
+            Some(v) => &v,
+            None => "",
+        }
+    }
+    pub fn clear_added_by(&mut self) {
+        self.added_by.clear();
+    }
+
+    pub fn has_added_by(&self) -> bool {
+        self.added_by.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_added_by(&mut self, v: ::std::string::String) {
+        self.added_by = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_added_by(&mut self) -> &mut ::std::string::String {
+        if self.added_by.is_none() {
+            self.added_by.set_default();
+        }
+        self.added_by.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_added_by(&mut self) -> ::std::string::String {
+        self.added_by.take().unwrap_or_else(|| ::std::string::String::new())
+    }
+
+    // optional int64 timestamp = 2;
+
+
+    pub fn get_timestamp(&self) -> i64 {
+        self.timestamp.unwrap_or(0)
+    }
+    pub fn clear_timestamp(&mut self) {
+        self.timestamp = ::std::option::Option::None;
+    }
+
+    pub fn has_timestamp(&self) -> bool {
+        self.timestamp.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_timestamp(&mut self, v: i64) {
+        self.timestamp = ::std::option::Option::Some(v);
+    }
+
+    // optional string message = 3;
+
+
+    pub fn get_message(&self) -> &str {
+        match self.message.as_ref() {
+            Some(v) => &v,
+            None => "",
+        }
+    }
+    pub fn clear_message(&mut self) {
+        self.message.clear();
+    }
+
+    pub fn has_message(&self) -> bool {
+        self.message.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_message(&mut self, v: ::std::string::String) {
+        self.message = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_message(&mut self) -> &mut ::std::string::String {
+        if self.message.is_none() {
+            self.message.set_default();
+        }
+        self.message.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_message(&mut self) -> ::std::string::String {
+        self.message.take().unwrap_or_else(|| ::std::string::String::new())
+    }
+
+    // optional bool seen = 4;
+
+
+    pub fn get_seen(&self) -> bool {
+        self.seen.unwrap_or(false)
+    }
+    pub fn clear_seen(&mut self) {
+        self.seen = ::std::option::Option::None;
+    }
+
+    pub fn has_seen(&self) -> bool {
+        self.seen.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_seen(&mut self, v: bool) {
+        self.seen = ::std::option::Option::Some(v);
+    }
+
+    // optional int64 download_count = 5;
+
+
+    pub fn get_download_count(&self) -> i64 {
+        self.download_count.unwrap_or(0)
+    }
+    pub fn clear_download_count(&mut self) {
+        self.download_count = ::std::option::Option::None;
+    }
+
+    pub fn has_download_count(&self) -> bool {
+        self.download_count.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_download_count(&mut self, v: i64) {
+        self.download_count = ::std::option::Option::Some(v);
+    }
+
+    // optional .DownloadFormat download_format = 6;
+
+
+    pub fn get_download_format(&self) -> &DownloadFormat {
+        self.download_format.as_ref().unwrap_or_else(|| DownloadFormat::default_instance())
+    }
+    pub fn clear_download_format(&mut self) {
+        self.download_format.clear();
+    }
+
+    pub fn has_download_format(&self) -> bool {
+        self.download_format.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_download_format(&mut self, v: DownloadFormat) {
+        self.download_format = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_download_format(&mut self) -> &mut DownloadFormat {
+        if self.download_format.is_none() {
+            self.download_format.set_default();
+        }
+        self.download_format.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_download_format(&mut self) -> DownloadFormat {
+        self.download_format.take().unwrap_or_else(|| DownloadFormat::new())
+    }
+
+    // optional string sevendigital_id = 7;
+
+
+    pub fn get_sevendigital_id(&self) -> &str {
+        match self.sevendigital_id.as_ref() {
+            Some(v) => &v,
+            None => "",
+        }
+    }
+    pub fn clear_sevendigital_id(&mut self) {
+        self.sevendigital_id.clear();
+    }
+
+    pub fn has_sevendigital_id(&self) -> bool {
+        self.sevendigital_id.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_sevendigital_id(&mut self, v: ::std::string::String) {
+        self.sevendigital_id = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_sevendigital_id(&mut self) -> &mut ::std::string::String {
+        if self.sevendigital_id.is_none() {
+            self.sevendigital_id.set_default();
+        }
+        self.sevendigital_id.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_sevendigital_id(&mut self) -> ::std::string::String {
+        self.sevendigital_id.take().unwrap_or_else(|| ::std::string::String::new())
+    }
+
+    // optional int64 sevendigital_left = 8;
+
+
+    pub fn get_sevendigital_left(&self) -> i64 {
+        self.sevendigital_left.unwrap_or(0)
+    }
+    pub fn clear_sevendigital_left(&mut self) {
+        self.sevendigital_left = ::std::option::Option::None;
+    }
+
+    pub fn has_sevendigital_left(&self) -> bool {
+        self.sevendigital_left.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_sevendigital_left(&mut self, v: i64) {
+        self.sevendigital_left = ::std::option::Option::Some(v);
+    }
+
+    // optional int64 seen_at = 9;
+
+
+    pub fn get_seen_at(&self) -> i64 {
+        self.seen_at.unwrap_or(0)
+    }
+    pub fn clear_seen_at(&mut self) {
+        self.seen_at = ::std::option::Option::None;
+    }
+
+    pub fn has_seen_at(&self) -> bool {
+        self.seen_at.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_seen_at(&mut self, v: i64) {
+        self.seen_at = ::std::option::Option::Some(v);
+    }
+
+    // optional bool public = 10;
+
+
+    pub fn get_public(&self) -> bool {
+        self.public.unwrap_or(false)
+    }
+    pub fn clear_public(&mut self) {
+        self.public = ::std::option::Option::None;
+    }
+
+    pub fn has_public(&self) -> bool {
+        self.public.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_public(&mut self, v: bool) {
+        self.public = ::std::option::Option::Some(v);
+    }
+}
+
+impl ::protobuf::Message for ItemAttributes {
+    fn is_initialized(&self) -> bool {
+        for v in &self.download_format {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.added_by)?;
+                },
+                2 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int64()?;
+                    self.timestamp = ::std::option::Option::Some(tmp);
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.message)?;
+                },
+                4 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.seen = ::std::option::Option::Some(tmp);
+                },
+                5 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int64()?;
+                    self.download_count = ::std::option::Option::Some(tmp);
+                },
+                6 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.download_format)?;
+                },
+                7 => {
+                    ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.sevendigital_id)?;
+                },
+                8 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int64()?;
+                    self.sevendigital_left = ::std::option::Option::Some(tmp);
+                },
+                9 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int64()?;
+                    self.seen_at = ::std::option::Option::Some(tmp);
+                },
+                10 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.public = ::std::option::Option::Some(tmp);
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.added_by.as_ref() {
+            my_size += ::protobuf::rt::string_size(1, &v);
+        }
+        if let Some(v) = self.timestamp {
+            my_size += ::protobuf::rt::value_size(2, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(ref v) = self.message.as_ref() {
+            my_size += ::protobuf::rt::string_size(3, &v);
+        }
+        if let Some(v) = self.seen {
+            my_size += 2;
+        }
+        if let Some(v) = self.download_count {
+            my_size += ::protobuf::rt::value_size(5, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(ref v) = self.download_format.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.sevendigital_id.as_ref() {
+            my_size += ::protobuf::rt::string_size(7, &v);
+        }
+        if let Some(v) = self.sevendigital_left {
+            my_size += ::protobuf::rt::value_size(8, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(v) = self.seen_at {
+            my_size += ::protobuf::rt::value_size(9, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(v) = self.public {
+            my_size += 2;
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.added_by.as_ref() {
+            os.write_string(1, &v)?;
+        }
+        if let Some(v) = self.timestamp {
+            os.write_int64(2, v)?;
+        }
+        if let Some(ref v) = self.message.as_ref() {
+            os.write_string(3, &v)?;
+        }
+        if let Some(v) = self.seen {
+            os.write_bool(4, v)?;
+        }
+        if let Some(v) = self.download_count {
+            os.write_int64(5, v)?;
+        }
+        if let Some(ref v) = self.download_format.as_ref() {
+            os.write_tag(6, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.sevendigital_id.as_ref() {
+            os.write_string(7, &v)?;
+        }
+        if let Some(v) = self.sevendigital_left {
+            os.write_int64(8, v)?;
+        }
+        if let Some(v) = self.seen_at {
+            os.write_int64(9, v)?;
+        }
+        if let Some(v) = self.public {
+            os.write_bool(10, v)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ItemAttributes {
+        ItemAttributes::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                    "added_by",
+                    |m: &ItemAttributes| { &m.added_by },
+                    |m: &mut ItemAttributes| { &mut m.added_by },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt64>(
+                    "timestamp",
+                    |m: &ItemAttributes| { &m.timestamp },
+                    |m: &mut ItemAttributes| { &mut m.timestamp },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                    "message",
+                    |m: &ItemAttributes| { &m.message },
+                    |m: &mut ItemAttributes| { &mut m.message },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "seen",
+                    |m: &ItemAttributes| { &m.seen },
+                    |m: &mut ItemAttributes| { &mut m.seen },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt64>(
+                    "download_count",
+                    |m: &ItemAttributes| { &m.download_count },
+                    |m: &mut ItemAttributes| { &mut m.download_count },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<DownloadFormat>>(
+                    "download_format",
+                    |m: &ItemAttributes| { &m.download_format },
+                    |m: &mut ItemAttributes| { &mut m.download_format },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                    "sevendigital_id",
+                    |m: &ItemAttributes| { &m.sevendigital_id },
+                    |m: &mut ItemAttributes| { &mut m.sevendigital_id },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt64>(
+                    "sevendigital_left",
+                    |m: &ItemAttributes| { &m.sevendigital_left },
+                    |m: &mut ItemAttributes| { &mut m.sevendigital_left },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt64>(
+                    "seen_at",
+                    |m: &ItemAttributes| { &m.seen_at },
+                    |m: &mut ItemAttributes| { &mut m.seen_at },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "public",
+                    |m: &ItemAttributes| { &m.public },
+                    |m: &mut ItemAttributes| { &mut m.public },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<ItemAttributes>(
+                    "ItemAttributes",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static ItemAttributes {
+        static mut instance: ::protobuf::lazy::Lazy<ItemAttributes> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ItemAttributes,
+        };
+        unsafe {
+            instance.get(ItemAttributes::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for ItemAttributes {
+    fn clear(&mut self) {
+        self.added_by.clear();
+        self.timestamp = ::std::option::Option::None;
+        self.message.clear();
+        self.seen = ::std::option::Option::None;
+        self.download_count = ::std::option::Option::None;
+        self.download_format.clear();
+        self.sevendigital_id.clear();
+        self.sevendigital_left = ::std::option::Option::None;
+        self.seen_at = ::std::option::Option::None;
+        self.public = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ItemAttributes {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ItemAttributes {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct StringAttribute {
+    // message fields
+    key: ::protobuf::SingularField<::std::string::String>,
+    value: ::protobuf::SingularField<::std::string::String>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a StringAttribute {
+    fn default() -> &'a StringAttribute {
+        <StringAttribute as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl StringAttribute {
+    pub fn new() -> StringAttribute {
+        ::std::default::Default::default()
+    }
+
+    // optional string key = 1;
+
+
+    pub fn get_key(&self) -> &str {
+        match self.key.as_ref() {
+            Some(v) => &v,
+            None => "",
+        }
+    }
+    pub fn clear_key(&mut self) {
+        self.key.clear();
+    }
+
+    pub fn has_key(&self) -> bool {
+        self.key.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_key(&mut self, v: ::std::string::String) {
+        self.key = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_key(&mut self) -> &mut ::std::string::String {
+        if self.key.is_none() {
+            self.key.set_default();
+        }
+        self.key.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_key(&mut self) -> ::std::string::String {
+        self.key.take().unwrap_or_else(|| ::std::string::String::new())
+    }
+
+    // optional string value = 2;
+
+
+    pub fn get_value(&self) -> &str {
+        match self.value.as_ref() {
+            Some(v) => &v,
+            None => "",
+        }
+    }
+    pub fn clear_value(&mut self) {
+        self.value.clear();
+    }
+
+    pub fn has_value(&self) -> bool {
+        self.value.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_value(&mut self, v: ::std::string::String) {
+        self.value = ::protobuf::SingularField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_value(&mut self) -> &mut ::std::string::String {
+        if self.value.is_none() {
+            self.value.set_default();
+        }
+        self.value.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_value(&mut self) -> ::std::string::String {
+        self.value.take().unwrap_or_else(|| ::std::string::String::new())
+    }
+}
+
+impl ::protobuf::Message for StringAttribute {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.key)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.value)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.key.as_ref() {
+            my_size += ::protobuf::rt::string_size(1, &v);
+        }
+        if let Some(ref v) = self.value.as_ref() {
+            my_size += ::protobuf::rt::string_size(2, &v);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.key.as_ref() {
+            os.write_string(1, &v)?;
+        }
+        if let Some(ref v) = self.value.as_ref() {
+            os.write_string(2, &v)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> StringAttribute {
+        StringAttribute::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                    "key",
+                    |m: &StringAttribute| { &m.key },
+                    |m: &mut StringAttribute| { &mut m.key },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                    "value",
+                    |m: &StringAttribute| { &m.value },
+                    |m: &mut StringAttribute| { &mut m.value },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<StringAttribute>(
+                    "StringAttribute",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static StringAttribute {
+        static mut instance: ::protobuf::lazy::Lazy<StringAttribute> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const StringAttribute,
+        };
+        unsafe {
+            instance.get(StringAttribute::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for StringAttribute {
+    fn clear(&mut self) {
+        self.key.clear();
+        self.value.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for StringAttribute {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for StringAttribute {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct StringAttributes {
+    // message fields
+    attribute: ::protobuf::RepeatedField<StringAttribute>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a StringAttributes {
+    fn default() -> &'a StringAttributes {
+        <StringAttributes as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl StringAttributes {
+    pub fn new() -> StringAttributes {
+        ::std::default::Default::default()
+    }
+
+    // repeated .StringAttribute attribute = 1;
+
+
+    pub fn get_attribute(&self) -> &[StringAttribute] {
+        &self.attribute
+    }
+    pub fn clear_attribute(&mut self) {
+        self.attribute.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_attribute(&mut self, v: ::protobuf::RepeatedField<StringAttribute>) {
+        self.attribute = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_attribute(&mut self) -> &mut ::protobuf::RepeatedField<StringAttribute> {
+        &mut self.attribute
+    }
+
+    // Take field
+    pub fn take_attribute(&mut self) -> ::protobuf::RepeatedField<StringAttribute> {
+        ::std::mem::replace(&mut self.attribute, ::protobuf::RepeatedField::new())
+    }
+}
+
+impl ::protobuf::Message for StringAttributes {
+    fn is_initialized(&self) -> bool {
+        for v in &self.attribute {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.attribute)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        for value in &self.attribute {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        for v in &self.attribute {
+            os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> StringAttributes {
+        StringAttributes::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<StringAttribute>>(
+                    "attribute",
+                    |m: &StringAttributes| { &m.attribute },
+                    |m: &mut StringAttributes| { &mut m.attribute },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<StringAttributes>(
+                    "StringAttributes",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static StringAttributes {
+        static mut instance: ::protobuf::lazy::Lazy<StringAttributes> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const StringAttributes,
+        };
+        unsafe {
+            instance.get(StringAttributes::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for StringAttributes {
+    fn clear(&mut self) {
+        self.attribute.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for StringAttributes {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for StringAttributes {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+static file_descriptor_proto_data: &'static [u8] = b"\
+    \n\x13playlist4meta.proto\x12\0\"3\n\x0cListChecksum\x12\x11\n\x07versio\
+    n\x18\x01\x20\x01(\x05B\0\x12\x0e\n\x04sha1\x18\x04\x20\x01(\x0cB\0:\0\"\
+    \x86\x01\n\x0eDownloadFormat\x12&\n\x05codec\x18\x01\x20\x01(\x0e2\x15.D\
+    ownloadFormat.CodecB\0\"J\n\x05Codec\x12\x11\n\rCODEC_UNKNOWN\x10\0\x12\
+    \x0e\n\nOGG_VORBIS\x10\x01\x12\x08\n\x04FLAC\x10\x02\x12\x12\n\x0eMPEG_1\
+    _LAYER_3\x10\x03\x1a\0:\0\"\x8b\x02\n\x0eListAttributes\x12\x0e\n\x04nam\
+    e\x18\x01\x20\x01(\tB\0\x12\x15\n\x0bdescription\x18\x02\x20\x01(\tB\0\
+    \x12\x11\n\x07picture\x18\x03\x20\x01(\x0cB\0\x12\x17\n\rcollaborative\
+    \x18\x04\x20\x01(\x08B\0\x12\x15\n\x0bpl3_version\x18\x05\x20\x01(\tB\0\
+    \x12\x1a\n\x10deleted_by_owner\x18\x06\x20\x01(\x08B\0\x12\"\n\x18restri\
+    cted_collaborative\x18\x07\x20\x01(\x08B\0\x12\x1e\n\x14deprecated_clien\
+    t_id\x18\x08\x20\x01(\x03B\0\x12\x18\n\x0epublic_starred\x18\t\x20\x01(\
+    \x08B\0\x12\x13\n\tclient_id\x18\n\x20\x01(\tB\0:\0\"\x81\x02\n\x0eItemA\
+    ttributes\x12\x12\n\x08added_by\x18\x01\x20\x01(\tB\0\x12\x13\n\ttimesta\
+    mp\x18\x02\x20\x01(\x03B\0\x12\x11\n\x07message\x18\x03\x20\x01(\tB\0\
+    \x12\x0e\n\x04seen\x18\x04\x20\x01(\x08B\0\x12\x18\n\x0edownload_count\
+    \x18\x05\x20\x01(\x03B\0\x12*\n\x0fdownload_format\x18\x06\x20\x01(\x0b2\
+    \x0f.DownloadFormatB\0\x12\x19\n\x0fsevendigital_id\x18\x07\x20\x01(\tB\
+    \0\x12\x1b\n\x11sevendigital_left\x18\x08\x20\x01(\x03B\0\x12\x11\n\x07s\
+    een_at\x18\t\x20\x01(\x03B\0\x12\x10\n\x06public\x18\n\x20\x01(\x08B\0:\
+    \0\"3\n\x0fStringAttribute\x12\r\n\x03key\x18\x01\x20\x01(\tB\0\x12\x0f\
+    \n\x05value\x18\x02\x20\x01(\tB\0:\0\";\n\x10StringAttributes\x12%\n\tat\
+    tribute\x18\x01\x20\x03(\x0b2\x10.StringAttributeB\0:\0B\0b\x06proto2\
+";
+
+static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy {
+    lock: ::protobuf::lazy::ONCE_INIT,
+    ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto,
+};
+
+fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
+    ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()
+}
+
+pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
+    unsafe {
+        file_descriptor_proto_lazy.get(|| {
+            parse_descriptor_proto()
+        })
+    }
+}

+ 3371 - 0
protocol/src/playlist4ops.rs

@@ -0,0 +1,3371 @@
+// This file is generated by rust-protobuf 2.7.0. Do not edit
+// @generated
+
+// https://github.com/Manishearth/rust-clippy/issues/702
+#![allow(unknown_lints)]
+#![allow(clippy::all)]
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+
+#![allow(box_pointers)]
+#![allow(dead_code)]
+#![allow(missing_docs)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![allow(trivial_casts)]
+#![allow(unsafe_code)]
+#![allow(unused_imports)]
+#![allow(unused_results)]
+//! Generated file from `playlist4ops.proto`
+
+use protobuf::Message as Message_imported_for_functions;
+use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
+
+/// Generated files are compatible only with the same version
+/// of protobuf runtime.
+const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_7_0;
+
+#[derive(PartialEq,Clone,Default)]
+pub struct Add {
+    // message fields
+    fromIndex: ::std::option::Option<i32>,
+    items: ::protobuf::RepeatedField<super::playlist4content::Item>,
+    list_checksum: ::protobuf::SingularPtrField<super::playlist4meta::ListChecksum>,
+    addLast: ::std::option::Option<bool>,
+    addFirst: ::std::option::Option<bool>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a Add {
+    fn default() -> &'a Add {
+        <Add as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl Add {
+    pub fn new() -> Add {
+        ::std::default::Default::default()
+    }
+
+    // optional int32 fromIndex = 1;
+
+
+    pub fn get_fromIndex(&self) -> i32 {
+        self.fromIndex.unwrap_or(0)
+    }
+    pub fn clear_fromIndex(&mut self) {
+        self.fromIndex = ::std::option::Option::None;
+    }
+
+    pub fn has_fromIndex(&self) -> bool {
+        self.fromIndex.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_fromIndex(&mut self, v: i32) {
+        self.fromIndex = ::std::option::Option::Some(v);
+    }
+
+    // repeated .Item items = 2;
+
+
+    pub fn get_items(&self) -> &[super::playlist4content::Item] {
+        &self.items
+    }
+    pub fn clear_items(&mut self) {
+        self.items.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_items(&mut self, v: ::protobuf::RepeatedField<super::playlist4content::Item>) {
+        self.items = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField<super::playlist4content::Item> {
+        &mut self.items
+    }
+
+    // Take field
+    pub fn take_items(&mut self) -> ::protobuf::RepeatedField<super::playlist4content::Item> {
+        ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new())
+    }
+
+    // optional .ListChecksum list_checksum = 3;
+
+
+    pub fn get_list_checksum(&self) -> &super::playlist4meta::ListChecksum {
+        self.list_checksum.as_ref().unwrap_or_else(|| super::playlist4meta::ListChecksum::default_instance())
+    }
+    pub fn clear_list_checksum(&mut self) {
+        self.list_checksum.clear();
+    }
+
+    pub fn has_list_checksum(&self) -> bool {
+        self.list_checksum.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_list_checksum(&mut self, v: super::playlist4meta::ListChecksum) {
+        self.list_checksum = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_list_checksum(&mut self) -> &mut super::playlist4meta::ListChecksum {
+        if self.list_checksum.is_none() {
+            self.list_checksum.set_default();
+        }
+        self.list_checksum.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_list_checksum(&mut self) -> super::playlist4meta::ListChecksum {
+        self.list_checksum.take().unwrap_or_else(|| super::playlist4meta::ListChecksum::new())
+    }
+
+    // optional bool addLast = 4;
+
+
+    pub fn get_addLast(&self) -> bool {
+        self.addLast.unwrap_or(false)
+    }
+    pub fn clear_addLast(&mut self) {
+        self.addLast = ::std::option::Option::None;
+    }
+
+    pub fn has_addLast(&self) -> bool {
+        self.addLast.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_addLast(&mut self, v: bool) {
+        self.addLast = ::std::option::Option::Some(v);
+    }
+
+    // optional bool addFirst = 5;
+
+
+    pub fn get_addFirst(&self) -> bool {
+        self.addFirst.unwrap_or(false)
+    }
+    pub fn clear_addFirst(&mut self) {
+        self.addFirst = ::std::option::Option::None;
+    }
+
+    pub fn has_addFirst(&self) -> bool {
+        self.addFirst.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_addFirst(&mut self, v: bool) {
+        self.addFirst = ::std::option::Option::Some(v);
+    }
+}
+
+impl ::protobuf::Message for Add {
+    fn is_initialized(&self) -> bool {
+        for v in &self.items {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.list_checksum {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.fromIndex = ::std::option::Option::Some(tmp);
+                },
+                2 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.list_checksum)?;
+                },
+                4 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.addLast = ::std::option::Option::Some(tmp);
+                },
+                5 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.addFirst = ::std::option::Option::Some(tmp);
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(v) = self.fromIndex {
+            my_size += ::protobuf::rt::value_size(1, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        for value in &self.items {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        if let Some(ref v) = self.list_checksum.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(v) = self.addLast {
+            my_size += 2;
+        }
+        if let Some(v) = self.addFirst {
+            my_size += 2;
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(v) = self.fromIndex {
+            os.write_int32(1, v)?;
+        }
+        for v in &self.items {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        if let Some(ref v) = self.list_checksum.as_ref() {
+            os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(v) = self.addLast {
+            os.write_bool(4, v)?;
+        }
+        if let Some(v) = self.addFirst {
+            os.write_bool(5, v)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> Add {
+        Add::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "fromIndex",
+                    |m: &Add| { &m.fromIndex },
+                    |m: &mut Add| { &mut m.fromIndex },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4content::Item>>(
+                    "items",
+                    |m: &Add| { &m.items },
+                    |m: &mut Add| { &mut m.items },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListChecksum>>(
+                    "list_checksum",
+                    |m: &Add| { &m.list_checksum },
+                    |m: &mut Add| { &mut m.list_checksum },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "addLast",
+                    |m: &Add| { &m.addLast },
+                    |m: &mut Add| { &mut m.addLast },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "addFirst",
+                    |m: &Add| { &m.addFirst },
+                    |m: &mut Add| { &mut m.addFirst },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<Add>(
+                    "Add",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static Add {
+        static mut instance: ::protobuf::lazy::Lazy<Add> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const Add,
+        };
+        unsafe {
+            instance.get(Add::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for Add {
+    fn clear(&mut self) {
+        self.fromIndex = ::std::option::Option::None;
+        self.items.clear();
+        self.list_checksum.clear();
+        self.addLast = ::std::option::Option::None;
+        self.addFirst = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for Add {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for Add {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct Rem {
+    // message fields
+    fromIndex: ::std::option::Option<i32>,
+    length: ::std::option::Option<i32>,
+    items: ::protobuf::RepeatedField<super::playlist4content::Item>,
+    list_checksum: ::protobuf::SingularPtrField<super::playlist4meta::ListChecksum>,
+    items_checksum: ::protobuf::SingularPtrField<super::playlist4meta::ListChecksum>,
+    uris_checksum: ::protobuf::SingularPtrField<super::playlist4meta::ListChecksum>,
+    itemsAsKey: ::std::option::Option<bool>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a Rem {
+    fn default() -> &'a Rem {
+        <Rem as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl Rem {
+    pub fn new() -> Rem {
+        ::std::default::Default::default()
+    }
+
+    // optional int32 fromIndex = 1;
+
+
+    pub fn get_fromIndex(&self) -> i32 {
+        self.fromIndex.unwrap_or(0)
+    }
+    pub fn clear_fromIndex(&mut self) {
+        self.fromIndex = ::std::option::Option::None;
+    }
+
+    pub fn has_fromIndex(&self) -> bool {
+        self.fromIndex.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_fromIndex(&mut self, v: i32) {
+        self.fromIndex = ::std::option::Option::Some(v);
+    }
+
+    // optional int32 length = 2;
+
+
+    pub fn get_length(&self) -> i32 {
+        self.length.unwrap_or(0)
+    }
+    pub fn clear_length(&mut self) {
+        self.length = ::std::option::Option::None;
+    }
+
+    pub fn has_length(&self) -> bool {
+        self.length.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_length(&mut self, v: i32) {
+        self.length = ::std::option::Option::Some(v);
+    }
+
+    // repeated .Item items = 3;
+
+
+    pub fn get_items(&self) -> &[super::playlist4content::Item] {
+        &self.items
+    }
+    pub fn clear_items(&mut self) {
+        self.items.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_items(&mut self, v: ::protobuf::RepeatedField<super::playlist4content::Item>) {
+        self.items = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField<super::playlist4content::Item> {
+        &mut self.items
+    }
+
+    // Take field
+    pub fn take_items(&mut self) -> ::protobuf::RepeatedField<super::playlist4content::Item> {
+        ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new())
+    }
+
+    // optional .ListChecksum list_checksum = 4;
+
+
+    pub fn get_list_checksum(&self) -> &super::playlist4meta::ListChecksum {
+        self.list_checksum.as_ref().unwrap_or_else(|| super::playlist4meta::ListChecksum::default_instance())
+    }
+    pub fn clear_list_checksum(&mut self) {
+        self.list_checksum.clear();
+    }
+
+    pub fn has_list_checksum(&self) -> bool {
+        self.list_checksum.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_list_checksum(&mut self, v: super::playlist4meta::ListChecksum) {
+        self.list_checksum = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_list_checksum(&mut self) -> &mut super::playlist4meta::ListChecksum {
+        if self.list_checksum.is_none() {
+            self.list_checksum.set_default();
+        }
+        self.list_checksum.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_list_checksum(&mut self) -> super::playlist4meta::ListChecksum {
+        self.list_checksum.take().unwrap_or_else(|| super::playlist4meta::ListChecksum::new())
+    }
+
+    // optional .ListChecksum items_checksum = 5;
+
+
+    pub fn get_items_checksum(&self) -> &super::playlist4meta::ListChecksum {
+        self.items_checksum.as_ref().unwrap_or_else(|| super::playlist4meta::ListChecksum::default_instance())
+    }
+    pub fn clear_items_checksum(&mut self) {
+        self.items_checksum.clear();
+    }
+
+    pub fn has_items_checksum(&self) -> bool {
+        self.items_checksum.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_items_checksum(&mut self, v: super::playlist4meta::ListChecksum) {
+        self.items_checksum = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_items_checksum(&mut self) -> &mut super::playlist4meta::ListChecksum {
+        if self.items_checksum.is_none() {
+            self.items_checksum.set_default();
+        }
+        self.items_checksum.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_items_checksum(&mut self) -> super::playlist4meta::ListChecksum {
+        self.items_checksum.take().unwrap_or_else(|| super::playlist4meta::ListChecksum::new())
+    }
+
+    // optional .ListChecksum uris_checksum = 6;
+
+
+    pub fn get_uris_checksum(&self) -> &super::playlist4meta::ListChecksum {
+        self.uris_checksum.as_ref().unwrap_or_else(|| super::playlist4meta::ListChecksum::default_instance())
+    }
+    pub fn clear_uris_checksum(&mut self) {
+        self.uris_checksum.clear();
+    }
+
+    pub fn has_uris_checksum(&self) -> bool {
+        self.uris_checksum.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_uris_checksum(&mut self, v: super::playlist4meta::ListChecksum) {
+        self.uris_checksum = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_uris_checksum(&mut self) -> &mut super::playlist4meta::ListChecksum {
+        if self.uris_checksum.is_none() {
+            self.uris_checksum.set_default();
+        }
+        self.uris_checksum.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_uris_checksum(&mut self) -> super::playlist4meta::ListChecksum {
+        self.uris_checksum.take().unwrap_or_else(|| super::playlist4meta::ListChecksum::new())
+    }
+
+    // optional bool itemsAsKey = 7;
+
+
+    pub fn get_itemsAsKey(&self) -> bool {
+        self.itemsAsKey.unwrap_or(false)
+    }
+    pub fn clear_itemsAsKey(&mut self) {
+        self.itemsAsKey = ::std::option::Option::None;
+    }
+
+    pub fn has_itemsAsKey(&self) -> bool {
+        self.itemsAsKey.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_itemsAsKey(&mut self, v: bool) {
+        self.itemsAsKey = ::std::option::Option::Some(v);
+    }
+}
+
+impl ::protobuf::Message for Rem {
+    fn is_initialized(&self) -> bool {
+        for v in &self.items {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.list_checksum {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.items_checksum {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.uris_checksum {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.fromIndex = ::std::option::Option::Some(tmp);
+                },
+                2 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.length = ::std::option::Option::Some(tmp);
+                },
+                3 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?;
+                },
+                4 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.list_checksum)?;
+                },
+                5 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.items_checksum)?;
+                },
+                6 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.uris_checksum)?;
+                },
+                7 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.itemsAsKey = ::std::option::Option::Some(tmp);
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(v) = self.fromIndex {
+            my_size += ::protobuf::rt::value_size(1, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(v) = self.length {
+            my_size += ::protobuf::rt::value_size(2, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        for value in &self.items {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        if let Some(ref v) = self.list_checksum.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.items_checksum.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.uris_checksum.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(v) = self.itemsAsKey {
+            my_size += 2;
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(v) = self.fromIndex {
+            os.write_int32(1, v)?;
+        }
+        if let Some(v) = self.length {
+            os.write_int32(2, v)?;
+        }
+        for v in &self.items {
+            os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        if let Some(ref v) = self.list_checksum.as_ref() {
+            os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.items_checksum.as_ref() {
+            os.write_tag(5, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.uris_checksum.as_ref() {
+            os.write_tag(6, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(v) = self.itemsAsKey {
+            os.write_bool(7, v)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> Rem {
+        Rem::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "fromIndex",
+                    |m: &Rem| { &m.fromIndex },
+                    |m: &mut Rem| { &mut m.fromIndex },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "length",
+                    |m: &Rem| { &m.length },
+                    |m: &mut Rem| { &mut m.length },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4content::Item>>(
+                    "items",
+                    |m: &Rem| { &m.items },
+                    |m: &mut Rem| { &mut m.items },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListChecksum>>(
+                    "list_checksum",
+                    |m: &Rem| { &m.list_checksum },
+                    |m: &mut Rem| { &mut m.list_checksum },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListChecksum>>(
+                    "items_checksum",
+                    |m: &Rem| { &m.items_checksum },
+                    |m: &mut Rem| { &mut m.items_checksum },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListChecksum>>(
+                    "uris_checksum",
+                    |m: &Rem| { &m.uris_checksum },
+                    |m: &mut Rem| { &mut m.uris_checksum },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                    "itemsAsKey",
+                    |m: &Rem| { &m.itemsAsKey },
+                    |m: &mut Rem| { &mut m.itemsAsKey },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<Rem>(
+                    "Rem",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static Rem {
+        static mut instance: ::protobuf::lazy::Lazy<Rem> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const Rem,
+        };
+        unsafe {
+            instance.get(Rem::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for Rem {
+    fn clear(&mut self) {
+        self.fromIndex = ::std::option::Option::None;
+        self.length = ::std::option::Option::None;
+        self.items.clear();
+        self.list_checksum.clear();
+        self.items_checksum.clear();
+        self.uris_checksum.clear();
+        self.itemsAsKey = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for Rem {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for Rem {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct Mov {
+    // message fields
+    fromIndex: ::std::option::Option<i32>,
+    length: ::std::option::Option<i32>,
+    toIndex: ::std::option::Option<i32>,
+    list_checksum: ::protobuf::SingularPtrField<super::playlist4meta::ListChecksum>,
+    items_checksum: ::protobuf::SingularPtrField<super::playlist4meta::ListChecksum>,
+    uris_checksum: ::protobuf::SingularPtrField<super::playlist4meta::ListChecksum>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a Mov {
+    fn default() -> &'a Mov {
+        <Mov as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl Mov {
+    pub fn new() -> Mov {
+        ::std::default::Default::default()
+    }
+
+    // optional int32 fromIndex = 1;
+
+
+    pub fn get_fromIndex(&self) -> i32 {
+        self.fromIndex.unwrap_or(0)
+    }
+    pub fn clear_fromIndex(&mut self) {
+        self.fromIndex = ::std::option::Option::None;
+    }
+
+    pub fn has_fromIndex(&self) -> bool {
+        self.fromIndex.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_fromIndex(&mut self, v: i32) {
+        self.fromIndex = ::std::option::Option::Some(v);
+    }
+
+    // optional int32 length = 2;
+
+
+    pub fn get_length(&self) -> i32 {
+        self.length.unwrap_or(0)
+    }
+    pub fn clear_length(&mut self) {
+        self.length = ::std::option::Option::None;
+    }
+
+    pub fn has_length(&self) -> bool {
+        self.length.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_length(&mut self, v: i32) {
+        self.length = ::std::option::Option::Some(v);
+    }
+
+    // optional int32 toIndex = 3;
+
+
+    pub fn get_toIndex(&self) -> i32 {
+        self.toIndex.unwrap_or(0)
+    }
+    pub fn clear_toIndex(&mut self) {
+        self.toIndex = ::std::option::Option::None;
+    }
+
+    pub fn has_toIndex(&self) -> bool {
+        self.toIndex.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_toIndex(&mut self, v: i32) {
+        self.toIndex = ::std::option::Option::Some(v);
+    }
+
+    // optional .ListChecksum list_checksum = 4;
+
+
+    pub fn get_list_checksum(&self) -> &super::playlist4meta::ListChecksum {
+        self.list_checksum.as_ref().unwrap_or_else(|| super::playlist4meta::ListChecksum::default_instance())
+    }
+    pub fn clear_list_checksum(&mut self) {
+        self.list_checksum.clear();
+    }
+
+    pub fn has_list_checksum(&self) -> bool {
+        self.list_checksum.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_list_checksum(&mut self, v: super::playlist4meta::ListChecksum) {
+        self.list_checksum = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_list_checksum(&mut self) -> &mut super::playlist4meta::ListChecksum {
+        if self.list_checksum.is_none() {
+            self.list_checksum.set_default();
+        }
+        self.list_checksum.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_list_checksum(&mut self) -> super::playlist4meta::ListChecksum {
+        self.list_checksum.take().unwrap_or_else(|| super::playlist4meta::ListChecksum::new())
+    }
+
+    // optional .ListChecksum items_checksum = 5;
+
+
+    pub fn get_items_checksum(&self) -> &super::playlist4meta::ListChecksum {
+        self.items_checksum.as_ref().unwrap_or_else(|| super::playlist4meta::ListChecksum::default_instance())
+    }
+    pub fn clear_items_checksum(&mut self) {
+        self.items_checksum.clear();
+    }
+
+    pub fn has_items_checksum(&self) -> bool {
+        self.items_checksum.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_items_checksum(&mut self, v: super::playlist4meta::ListChecksum) {
+        self.items_checksum = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_items_checksum(&mut self) -> &mut super::playlist4meta::ListChecksum {
+        if self.items_checksum.is_none() {
+            self.items_checksum.set_default();
+        }
+        self.items_checksum.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_items_checksum(&mut self) -> super::playlist4meta::ListChecksum {
+        self.items_checksum.take().unwrap_or_else(|| super::playlist4meta::ListChecksum::new())
+    }
+
+    // optional .ListChecksum uris_checksum = 6;
+
+
+    pub fn get_uris_checksum(&self) -> &super::playlist4meta::ListChecksum {
+        self.uris_checksum.as_ref().unwrap_or_else(|| super::playlist4meta::ListChecksum::default_instance())
+    }
+    pub fn clear_uris_checksum(&mut self) {
+        self.uris_checksum.clear();
+    }
+
+    pub fn has_uris_checksum(&self) -> bool {
+        self.uris_checksum.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_uris_checksum(&mut self, v: super::playlist4meta::ListChecksum) {
+        self.uris_checksum = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_uris_checksum(&mut self) -> &mut super::playlist4meta::ListChecksum {
+        if self.uris_checksum.is_none() {
+            self.uris_checksum.set_default();
+        }
+        self.uris_checksum.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_uris_checksum(&mut self) -> super::playlist4meta::ListChecksum {
+        self.uris_checksum.take().unwrap_or_else(|| super::playlist4meta::ListChecksum::new())
+    }
+}
+
+impl ::protobuf::Message for Mov {
+    fn is_initialized(&self) -> bool {
+        for v in &self.list_checksum {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.items_checksum {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.uris_checksum {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.fromIndex = ::std::option::Option::Some(tmp);
+                },
+                2 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.length = ::std::option::Option::Some(tmp);
+                },
+                3 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.toIndex = ::std::option::Option::Some(tmp);
+                },
+                4 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.list_checksum)?;
+                },
+                5 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.items_checksum)?;
+                },
+                6 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.uris_checksum)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(v) = self.fromIndex {
+            my_size += ::protobuf::rt::value_size(1, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(v) = self.length {
+            my_size += ::protobuf::rt::value_size(2, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(v) = self.toIndex {
+            my_size += ::protobuf::rt::value_size(3, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(ref v) = self.list_checksum.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.items_checksum.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.uris_checksum.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(v) = self.fromIndex {
+            os.write_int32(1, v)?;
+        }
+        if let Some(v) = self.length {
+            os.write_int32(2, v)?;
+        }
+        if let Some(v) = self.toIndex {
+            os.write_int32(3, v)?;
+        }
+        if let Some(ref v) = self.list_checksum.as_ref() {
+            os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.items_checksum.as_ref() {
+            os.write_tag(5, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.uris_checksum.as_ref() {
+            os.write_tag(6, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> Mov {
+        Mov::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "fromIndex",
+                    |m: &Mov| { &m.fromIndex },
+                    |m: &mut Mov| { &mut m.fromIndex },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "length",
+                    |m: &Mov| { &m.length },
+                    |m: &mut Mov| { &mut m.length },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "toIndex",
+                    |m: &Mov| { &m.toIndex },
+                    |m: &mut Mov| { &mut m.toIndex },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListChecksum>>(
+                    "list_checksum",
+                    |m: &Mov| { &m.list_checksum },
+                    |m: &mut Mov| { &mut m.list_checksum },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListChecksum>>(
+                    "items_checksum",
+                    |m: &Mov| { &m.items_checksum },
+                    |m: &mut Mov| { &mut m.items_checksum },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListChecksum>>(
+                    "uris_checksum",
+                    |m: &Mov| { &m.uris_checksum },
+                    |m: &mut Mov| { &mut m.uris_checksum },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<Mov>(
+                    "Mov",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static Mov {
+        static mut instance: ::protobuf::lazy::Lazy<Mov> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const Mov,
+        };
+        unsafe {
+            instance.get(Mov::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for Mov {
+    fn clear(&mut self) {
+        self.fromIndex = ::std::option::Option::None;
+        self.length = ::std::option::Option::None;
+        self.toIndex = ::std::option::Option::None;
+        self.list_checksum.clear();
+        self.items_checksum.clear();
+        self.uris_checksum.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for Mov {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for Mov {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ItemAttributesPartialState {
+    // message fields
+    values: ::protobuf::SingularPtrField<super::playlist4meta::ItemAttributes>,
+    no_value: ::std::vec::Vec<ItemAttributesPartialState_ItemAttributeKind>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ItemAttributesPartialState {
+    fn default() -> &'a ItemAttributesPartialState {
+        <ItemAttributesPartialState as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ItemAttributesPartialState {
+    pub fn new() -> ItemAttributesPartialState {
+        ::std::default::Default::default()
+    }
+
+    // optional .ItemAttributes values = 1;
+
+
+    pub fn get_values(&self) -> &super::playlist4meta::ItemAttributes {
+        self.values.as_ref().unwrap_or_else(|| super::playlist4meta::ItemAttributes::default_instance())
+    }
+    pub fn clear_values(&mut self) {
+        self.values.clear();
+    }
+
+    pub fn has_values(&self) -> bool {
+        self.values.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_values(&mut self, v: super::playlist4meta::ItemAttributes) {
+        self.values = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_values(&mut self) -> &mut super::playlist4meta::ItemAttributes {
+        if self.values.is_none() {
+            self.values.set_default();
+        }
+        self.values.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_values(&mut self) -> super::playlist4meta::ItemAttributes {
+        self.values.take().unwrap_or_else(|| super::playlist4meta::ItemAttributes::new())
+    }
+
+    // repeated .ItemAttributesPartialState.ItemAttributeKind no_value = 2;
+
+
+    pub fn get_no_value(&self) -> &[ItemAttributesPartialState_ItemAttributeKind] {
+        &self.no_value
+    }
+    pub fn clear_no_value(&mut self) {
+        self.no_value.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_no_value(&mut self, v: ::std::vec::Vec<ItemAttributesPartialState_ItemAttributeKind>) {
+        self.no_value = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_no_value(&mut self) -> &mut ::std::vec::Vec<ItemAttributesPartialState_ItemAttributeKind> {
+        &mut self.no_value
+    }
+
+    // Take field
+    pub fn take_no_value(&mut self) -> ::std::vec::Vec<ItemAttributesPartialState_ItemAttributeKind> {
+        ::std::mem::replace(&mut self.no_value, ::std::vec::Vec::new())
+    }
+}
+
+impl ::protobuf::Message for ItemAttributesPartialState {
+    fn is_initialized(&self) -> bool {
+        for v in &self.values {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.values)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_repeated_enum_with_unknown_fields_into(wire_type, is, &mut self.no_value, 2, &mut self.unknown_fields)?
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.values.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        for value in &self.no_value {
+            my_size += ::protobuf::rt::enum_size(2, *value);
+        };
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.values.as_ref() {
+            os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        for v in &self.no_value {
+            os.write_enum(2, v.value())?;
+        };
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ItemAttributesPartialState {
+        ItemAttributesPartialState::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ItemAttributes>>(
+                    "values",
+                    |m: &ItemAttributesPartialState| { &m.values },
+                    |m: &mut ItemAttributesPartialState| { &mut m.values },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_vec_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ItemAttributesPartialState_ItemAttributeKind>>(
+                    "no_value",
+                    |m: &ItemAttributesPartialState| { &m.no_value },
+                    |m: &mut ItemAttributesPartialState| { &mut m.no_value },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<ItemAttributesPartialState>(
+                    "ItemAttributesPartialState",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static ItemAttributesPartialState {
+        static mut instance: ::protobuf::lazy::Lazy<ItemAttributesPartialState> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ItemAttributesPartialState,
+        };
+        unsafe {
+            instance.get(ItemAttributesPartialState::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for ItemAttributesPartialState {
+    fn clear(&mut self) {
+        self.values.clear();
+        self.no_value.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ItemAttributesPartialState {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ItemAttributesPartialState {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(Clone,PartialEq,Eq,Debug,Hash)]
+pub enum ItemAttributesPartialState_ItemAttributeKind {
+    ITEM_UNKNOWN = 0,
+    ITEM_ADDED_BY = 1,
+    ITEM_TIMESTAMP = 2,
+    ITEM_MESSAGE = 3,
+    ITEM_SEEN = 4,
+    ITEM_DOWNLOAD_COUNT = 5,
+    ITEM_DOWNLOAD_FORMAT = 6,
+    ITEM_SEVENDIGITAL_ID = 7,
+    ITEM_SEVENDIGITAL_LEFT = 8,
+    ITEM_SEEN_AT = 9,
+    ITEM_PUBLIC = 10,
+}
+
+impl ::protobuf::ProtobufEnum for ItemAttributesPartialState_ItemAttributeKind {
+    fn value(&self) -> i32 {
+        *self as i32
+    }
+
+    fn from_i32(value: i32) -> ::std::option::Option<ItemAttributesPartialState_ItemAttributeKind> {
+        match value {
+            0 => ::std::option::Option::Some(ItemAttributesPartialState_ItemAttributeKind::ITEM_UNKNOWN),
+            1 => ::std::option::Option::Some(ItemAttributesPartialState_ItemAttributeKind::ITEM_ADDED_BY),
+            2 => ::std::option::Option::Some(ItemAttributesPartialState_ItemAttributeKind::ITEM_TIMESTAMP),
+            3 => ::std::option::Option::Some(ItemAttributesPartialState_ItemAttributeKind::ITEM_MESSAGE),
+            4 => ::std::option::Option::Some(ItemAttributesPartialState_ItemAttributeKind::ITEM_SEEN),
+            5 => ::std::option::Option::Some(ItemAttributesPartialState_ItemAttributeKind::ITEM_DOWNLOAD_COUNT),
+            6 => ::std::option::Option::Some(ItemAttributesPartialState_ItemAttributeKind::ITEM_DOWNLOAD_FORMAT),
+            7 => ::std::option::Option::Some(ItemAttributesPartialState_ItemAttributeKind::ITEM_SEVENDIGITAL_ID),
+            8 => ::std::option::Option::Some(ItemAttributesPartialState_ItemAttributeKind::ITEM_SEVENDIGITAL_LEFT),
+            9 => ::std::option::Option::Some(ItemAttributesPartialState_ItemAttributeKind::ITEM_SEEN_AT),
+            10 => ::std::option::Option::Some(ItemAttributesPartialState_ItemAttributeKind::ITEM_PUBLIC),
+            _ => ::std::option::Option::None
+        }
+    }
+
+    fn values() -> &'static [Self] {
+        static values: &'static [ItemAttributesPartialState_ItemAttributeKind] = &[
+            ItemAttributesPartialState_ItemAttributeKind::ITEM_UNKNOWN,
+            ItemAttributesPartialState_ItemAttributeKind::ITEM_ADDED_BY,
+            ItemAttributesPartialState_ItemAttributeKind::ITEM_TIMESTAMP,
+            ItemAttributesPartialState_ItemAttributeKind::ITEM_MESSAGE,
+            ItemAttributesPartialState_ItemAttributeKind::ITEM_SEEN,
+            ItemAttributesPartialState_ItemAttributeKind::ITEM_DOWNLOAD_COUNT,
+            ItemAttributesPartialState_ItemAttributeKind::ITEM_DOWNLOAD_FORMAT,
+            ItemAttributesPartialState_ItemAttributeKind::ITEM_SEVENDIGITAL_ID,
+            ItemAttributesPartialState_ItemAttributeKind::ITEM_SEVENDIGITAL_LEFT,
+            ItemAttributesPartialState_ItemAttributeKind::ITEM_SEEN_AT,
+            ItemAttributesPartialState_ItemAttributeKind::ITEM_PUBLIC,
+        ];
+        values
+    }
+
+    fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::EnumDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                ::protobuf::reflect::EnumDescriptor::new("ItemAttributesPartialState_ItemAttributeKind", file_descriptor_proto())
+            })
+        }
+    }
+}
+
+impl ::std::marker::Copy for ItemAttributesPartialState_ItemAttributeKind {
+}
+
+impl ::std::default::Default for ItemAttributesPartialState_ItemAttributeKind {
+    fn default() -> Self {
+        ItemAttributesPartialState_ItemAttributeKind::ITEM_UNKNOWN
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ItemAttributesPartialState_ItemAttributeKind {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor())
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ListAttributesPartialState {
+    // message fields
+    values: ::protobuf::SingularPtrField<super::playlist4meta::ListAttributes>,
+    no_value: ::std::vec::Vec<ListAttributesPartialState_ListAttributeKind>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ListAttributesPartialState {
+    fn default() -> &'a ListAttributesPartialState {
+        <ListAttributesPartialState as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ListAttributesPartialState {
+    pub fn new() -> ListAttributesPartialState {
+        ::std::default::Default::default()
+    }
+
+    // optional .ListAttributes values = 1;
+
+
+    pub fn get_values(&self) -> &super::playlist4meta::ListAttributes {
+        self.values.as_ref().unwrap_or_else(|| super::playlist4meta::ListAttributes::default_instance())
+    }
+    pub fn clear_values(&mut self) {
+        self.values.clear();
+    }
+
+    pub fn has_values(&self) -> bool {
+        self.values.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_values(&mut self, v: super::playlist4meta::ListAttributes) {
+        self.values = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_values(&mut self) -> &mut super::playlist4meta::ListAttributes {
+        if self.values.is_none() {
+            self.values.set_default();
+        }
+        self.values.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_values(&mut self) -> super::playlist4meta::ListAttributes {
+        self.values.take().unwrap_or_else(|| super::playlist4meta::ListAttributes::new())
+    }
+
+    // repeated .ListAttributesPartialState.ListAttributeKind no_value = 2;
+
+
+    pub fn get_no_value(&self) -> &[ListAttributesPartialState_ListAttributeKind] {
+        &self.no_value
+    }
+    pub fn clear_no_value(&mut self) {
+        self.no_value.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_no_value(&mut self, v: ::std::vec::Vec<ListAttributesPartialState_ListAttributeKind>) {
+        self.no_value = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_no_value(&mut self) -> &mut ::std::vec::Vec<ListAttributesPartialState_ListAttributeKind> {
+        &mut self.no_value
+    }
+
+    // Take field
+    pub fn take_no_value(&mut self) -> ::std::vec::Vec<ListAttributesPartialState_ListAttributeKind> {
+        ::std::mem::replace(&mut self.no_value, ::std::vec::Vec::new())
+    }
+}
+
+impl ::protobuf::Message for ListAttributesPartialState {
+    fn is_initialized(&self) -> bool {
+        for v in &self.values {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.values)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_repeated_enum_with_unknown_fields_into(wire_type, is, &mut self.no_value, 2, &mut self.unknown_fields)?
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.values.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        for value in &self.no_value {
+            my_size += ::protobuf::rt::enum_size(2, *value);
+        };
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.values.as_ref() {
+            os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        for v in &self.no_value {
+            os.write_enum(2, v.value())?;
+        };
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ListAttributesPartialState {
+        ListAttributesPartialState::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListAttributes>>(
+                    "values",
+                    |m: &ListAttributesPartialState| { &m.values },
+                    |m: &mut ListAttributesPartialState| { &mut m.values },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_vec_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ListAttributesPartialState_ListAttributeKind>>(
+                    "no_value",
+                    |m: &ListAttributesPartialState| { &m.no_value },
+                    |m: &mut ListAttributesPartialState| { &mut m.no_value },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<ListAttributesPartialState>(
+                    "ListAttributesPartialState",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static ListAttributesPartialState {
+        static mut instance: ::protobuf::lazy::Lazy<ListAttributesPartialState> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ListAttributesPartialState,
+        };
+        unsafe {
+            instance.get(ListAttributesPartialState::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for ListAttributesPartialState {
+    fn clear(&mut self) {
+        self.values.clear();
+        self.no_value.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ListAttributesPartialState {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ListAttributesPartialState {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(Clone,PartialEq,Eq,Debug,Hash)]
+pub enum ListAttributesPartialState_ListAttributeKind {
+    LIST_UNKNOWN = 0,
+    LIST_NAME = 1,
+    LIST_DESCRIPTION = 2,
+    LIST_PICTURE = 3,
+    LIST_COLLABORATIVE = 4,
+    LIST_PL3_VERSION = 5,
+    LIST_DELETED_BY_OWNER = 6,
+    LIST_RESTRICTED_COLLABORATIVE = 7,
+}
+
+impl ::protobuf::ProtobufEnum for ListAttributesPartialState_ListAttributeKind {
+    fn value(&self) -> i32 {
+        *self as i32
+    }
+
+    fn from_i32(value: i32) -> ::std::option::Option<ListAttributesPartialState_ListAttributeKind> {
+        match value {
+            0 => ::std::option::Option::Some(ListAttributesPartialState_ListAttributeKind::LIST_UNKNOWN),
+            1 => ::std::option::Option::Some(ListAttributesPartialState_ListAttributeKind::LIST_NAME),
+            2 => ::std::option::Option::Some(ListAttributesPartialState_ListAttributeKind::LIST_DESCRIPTION),
+            3 => ::std::option::Option::Some(ListAttributesPartialState_ListAttributeKind::LIST_PICTURE),
+            4 => ::std::option::Option::Some(ListAttributesPartialState_ListAttributeKind::LIST_COLLABORATIVE),
+            5 => ::std::option::Option::Some(ListAttributesPartialState_ListAttributeKind::LIST_PL3_VERSION),
+            6 => ::std::option::Option::Some(ListAttributesPartialState_ListAttributeKind::LIST_DELETED_BY_OWNER),
+            7 => ::std::option::Option::Some(ListAttributesPartialState_ListAttributeKind::LIST_RESTRICTED_COLLABORATIVE),
+            _ => ::std::option::Option::None
+        }
+    }
+
+    fn values() -> &'static [Self] {
+        static values: &'static [ListAttributesPartialState_ListAttributeKind] = &[
+            ListAttributesPartialState_ListAttributeKind::LIST_UNKNOWN,
+            ListAttributesPartialState_ListAttributeKind::LIST_NAME,
+            ListAttributesPartialState_ListAttributeKind::LIST_DESCRIPTION,
+            ListAttributesPartialState_ListAttributeKind::LIST_PICTURE,
+            ListAttributesPartialState_ListAttributeKind::LIST_COLLABORATIVE,
+            ListAttributesPartialState_ListAttributeKind::LIST_PL3_VERSION,
+            ListAttributesPartialState_ListAttributeKind::LIST_DELETED_BY_OWNER,
+            ListAttributesPartialState_ListAttributeKind::LIST_RESTRICTED_COLLABORATIVE,
+        ];
+        values
+    }
+
+    fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::EnumDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                ::protobuf::reflect::EnumDescriptor::new("ListAttributesPartialState_ListAttributeKind", file_descriptor_proto())
+            })
+        }
+    }
+}
+
+impl ::std::marker::Copy for ListAttributesPartialState_ListAttributeKind {
+}
+
+impl ::std::default::Default for ListAttributesPartialState_ListAttributeKind {
+    fn default() -> Self {
+        ListAttributesPartialState_ListAttributeKind::LIST_UNKNOWN
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ListAttributesPartialState_ListAttributeKind {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor())
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct UpdateItemAttributes {
+    // message fields
+    index: ::std::option::Option<i32>,
+    new_attributes: ::protobuf::SingularPtrField<ItemAttributesPartialState>,
+    old_attributes: ::protobuf::SingularPtrField<ItemAttributesPartialState>,
+    list_checksum: ::protobuf::SingularPtrField<super::playlist4meta::ListChecksum>,
+    old_attributes_checksum: ::protobuf::SingularPtrField<super::playlist4meta::ListChecksum>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a UpdateItemAttributes {
+    fn default() -> &'a UpdateItemAttributes {
+        <UpdateItemAttributes as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl UpdateItemAttributes {
+    pub fn new() -> UpdateItemAttributes {
+        ::std::default::Default::default()
+    }
+
+    // optional int32 index = 1;
+
+
+    pub fn get_index(&self) -> i32 {
+        self.index.unwrap_or(0)
+    }
+    pub fn clear_index(&mut self) {
+        self.index = ::std::option::Option::None;
+    }
+
+    pub fn has_index(&self) -> bool {
+        self.index.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_index(&mut self, v: i32) {
+        self.index = ::std::option::Option::Some(v);
+    }
+
+    // optional .ItemAttributesPartialState new_attributes = 2;
+
+
+    pub fn get_new_attributes(&self) -> &ItemAttributesPartialState {
+        self.new_attributes.as_ref().unwrap_or_else(|| ItemAttributesPartialState::default_instance())
+    }
+    pub fn clear_new_attributes(&mut self) {
+        self.new_attributes.clear();
+    }
+
+    pub fn has_new_attributes(&self) -> bool {
+        self.new_attributes.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_new_attributes(&mut self, v: ItemAttributesPartialState) {
+        self.new_attributes = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_new_attributes(&mut self) -> &mut ItemAttributesPartialState {
+        if self.new_attributes.is_none() {
+            self.new_attributes.set_default();
+        }
+        self.new_attributes.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_new_attributes(&mut self) -> ItemAttributesPartialState {
+        self.new_attributes.take().unwrap_or_else(|| ItemAttributesPartialState::new())
+    }
+
+    // optional .ItemAttributesPartialState old_attributes = 3;
+
+
+    pub fn get_old_attributes(&self) -> &ItemAttributesPartialState {
+        self.old_attributes.as_ref().unwrap_or_else(|| ItemAttributesPartialState::default_instance())
+    }
+    pub fn clear_old_attributes(&mut self) {
+        self.old_attributes.clear();
+    }
+
+    pub fn has_old_attributes(&self) -> bool {
+        self.old_attributes.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_old_attributes(&mut self, v: ItemAttributesPartialState) {
+        self.old_attributes = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_old_attributes(&mut self) -> &mut ItemAttributesPartialState {
+        if self.old_attributes.is_none() {
+            self.old_attributes.set_default();
+        }
+        self.old_attributes.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_old_attributes(&mut self) -> ItemAttributesPartialState {
+        self.old_attributes.take().unwrap_or_else(|| ItemAttributesPartialState::new())
+    }
+
+    // optional .ListChecksum list_checksum = 4;
+
+
+    pub fn get_list_checksum(&self) -> &super::playlist4meta::ListChecksum {
+        self.list_checksum.as_ref().unwrap_or_else(|| super::playlist4meta::ListChecksum::default_instance())
+    }
+    pub fn clear_list_checksum(&mut self) {
+        self.list_checksum.clear();
+    }
+
+    pub fn has_list_checksum(&self) -> bool {
+        self.list_checksum.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_list_checksum(&mut self, v: super::playlist4meta::ListChecksum) {
+        self.list_checksum = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_list_checksum(&mut self) -> &mut super::playlist4meta::ListChecksum {
+        if self.list_checksum.is_none() {
+            self.list_checksum.set_default();
+        }
+        self.list_checksum.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_list_checksum(&mut self) -> super::playlist4meta::ListChecksum {
+        self.list_checksum.take().unwrap_or_else(|| super::playlist4meta::ListChecksum::new())
+    }
+
+    // optional .ListChecksum old_attributes_checksum = 5;
+
+
+    pub fn get_old_attributes_checksum(&self) -> &super::playlist4meta::ListChecksum {
+        self.old_attributes_checksum.as_ref().unwrap_or_else(|| super::playlist4meta::ListChecksum::default_instance())
+    }
+    pub fn clear_old_attributes_checksum(&mut self) {
+        self.old_attributes_checksum.clear();
+    }
+
+    pub fn has_old_attributes_checksum(&self) -> bool {
+        self.old_attributes_checksum.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_old_attributes_checksum(&mut self, v: super::playlist4meta::ListChecksum) {
+        self.old_attributes_checksum = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_old_attributes_checksum(&mut self) -> &mut super::playlist4meta::ListChecksum {
+        if self.old_attributes_checksum.is_none() {
+            self.old_attributes_checksum.set_default();
+        }
+        self.old_attributes_checksum.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_old_attributes_checksum(&mut self) -> super::playlist4meta::ListChecksum {
+        self.old_attributes_checksum.take().unwrap_or_else(|| super::playlist4meta::ListChecksum::new())
+    }
+}
+
+impl ::protobuf::Message for UpdateItemAttributes {
+    fn is_initialized(&self) -> bool {
+        for v in &self.new_attributes {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.old_attributes {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.list_checksum {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.old_attributes_checksum {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.index = ::std::option::Option::Some(tmp);
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.new_attributes)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.old_attributes)?;
+                },
+                4 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.list_checksum)?;
+                },
+                5 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.old_attributes_checksum)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(v) = self.index {
+            my_size += ::protobuf::rt::value_size(1, v, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(ref v) = self.new_attributes.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.old_attributes.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.list_checksum.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.old_attributes_checksum.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(v) = self.index {
+            os.write_int32(1, v)?;
+        }
+        if let Some(ref v) = self.new_attributes.as_ref() {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.old_attributes.as_ref() {
+            os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.list_checksum.as_ref() {
+            os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.old_attributes_checksum.as_ref() {
+            os.write_tag(5, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> UpdateItemAttributes {
+        UpdateItemAttributes::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                    "index",
+                    |m: &UpdateItemAttributes| { &m.index },
+                    |m: &mut UpdateItemAttributes| { &mut m.index },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ItemAttributesPartialState>>(
+                    "new_attributes",
+                    |m: &UpdateItemAttributes| { &m.new_attributes },
+                    |m: &mut UpdateItemAttributes| { &mut m.new_attributes },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ItemAttributesPartialState>>(
+                    "old_attributes",
+                    |m: &UpdateItemAttributes| { &m.old_attributes },
+                    |m: &mut UpdateItemAttributes| { &mut m.old_attributes },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListChecksum>>(
+                    "list_checksum",
+                    |m: &UpdateItemAttributes| { &m.list_checksum },
+                    |m: &mut UpdateItemAttributes| { &mut m.list_checksum },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListChecksum>>(
+                    "old_attributes_checksum",
+                    |m: &UpdateItemAttributes| { &m.old_attributes_checksum },
+                    |m: &mut UpdateItemAttributes| { &mut m.old_attributes_checksum },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<UpdateItemAttributes>(
+                    "UpdateItemAttributes",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static UpdateItemAttributes {
+        static mut instance: ::protobuf::lazy::Lazy<UpdateItemAttributes> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const UpdateItemAttributes,
+        };
+        unsafe {
+            instance.get(UpdateItemAttributes::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for UpdateItemAttributes {
+    fn clear(&mut self) {
+        self.index = ::std::option::Option::None;
+        self.new_attributes.clear();
+        self.old_attributes.clear();
+        self.list_checksum.clear();
+        self.old_attributes_checksum.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for UpdateItemAttributes {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for UpdateItemAttributes {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct UpdateListAttributes {
+    // message fields
+    new_attributes: ::protobuf::SingularPtrField<ListAttributesPartialState>,
+    old_attributes: ::protobuf::SingularPtrField<ListAttributesPartialState>,
+    list_checksum: ::protobuf::SingularPtrField<super::playlist4meta::ListChecksum>,
+    old_attributes_checksum: ::protobuf::SingularPtrField<super::playlist4meta::ListChecksum>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a UpdateListAttributes {
+    fn default() -> &'a UpdateListAttributes {
+        <UpdateListAttributes as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl UpdateListAttributes {
+    pub fn new() -> UpdateListAttributes {
+        ::std::default::Default::default()
+    }
+
+    // optional .ListAttributesPartialState new_attributes = 1;
+
+
+    pub fn get_new_attributes(&self) -> &ListAttributesPartialState {
+        self.new_attributes.as_ref().unwrap_or_else(|| ListAttributesPartialState::default_instance())
+    }
+    pub fn clear_new_attributes(&mut self) {
+        self.new_attributes.clear();
+    }
+
+    pub fn has_new_attributes(&self) -> bool {
+        self.new_attributes.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_new_attributes(&mut self, v: ListAttributesPartialState) {
+        self.new_attributes = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_new_attributes(&mut self) -> &mut ListAttributesPartialState {
+        if self.new_attributes.is_none() {
+            self.new_attributes.set_default();
+        }
+        self.new_attributes.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_new_attributes(&mut self) -> ListAttributesPartialState {
+        self.new_attributes.take().unwrap_or_else(|| ListAttributesPartialState::new())
+    }
+
+    // optional .ListAttributesPartialState old_attributes = 2;
+
+
+    pub fn get_old_attributes(&self) -> &ListAttributesPartialState {
+        self.old_attributes.as_ref().unwrap_or_else(|| ListAttributesPartialState::default_instance())
+    }
+    pub fn clear_old_attributes(&mut self) {
+        self.old_attributes.clear();
+    }
+
+    pub fn has_old_attributes(&self) -> bool {
+        self.old_attributes.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_old_attributes(&mut self, v: ListAttributesPartialState) {
+        self.old_attributes = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_old_attributes(&mut self) -> &mut ListAttributesPartialState {
+        if self.old_attributes.is_none() {
+            self.old_attributes.set_default();
+        }
+        self.old_attributes.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_old_attributes(&mut self) -> ListAttributesPartialState {
+        self.old_attributes.take().unwrap_or_else(|| ListAttributesPartialState::new())
+    }
+
+    // optional .ListChecksum list_checksum = 3;
+
+
+    pub fn get_list_checksum(&self) -> &super::playlist4meta::ListChecksum {
+        self.list_checksum.as_ref().unwrap_or_else(|| super::playlist4meta::ListChecksum::default_instance())
+    }
+    pub fn clear_list_checksum(&mut self) {
+        self.list_checksum.clear();
+    }
+
+    pub fn has_list_checksum(&self) -> bool {
+        self.list_checksum.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_list_checksum(&mut self, v: super::playlist4meta::ListChecksum) {
+        self.list_checksum = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_list_checksum(&mut self) -> &mut super::playlist4meta::ListChecksum {
+        if self.list_checksum.is_none() {
+            self.list_checksum.set_default();
+        }
+        self.list_checksum.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_list_checksum(&mut self) -> super::playlist4meta::ListChecksum {
+        self.list_checksum.take().unwrap_or_else(|| super::playlist4meta::ListChecksum::new())
+    }
+
+    // optional .ListChecksum old_attributes_checksum = 4;
+
+
+    pub fn get_old_attributes_checksum(&self) -> &super::playlist4meta::ListChecksum {
+        self.old_attributes_checksum.as_ref().unwrap_or_else(|| super::playlist4meta::ListChecksum::default_instance())
+    }
+    pub fn clear_old_attributes_checksum(&mut self) {
+        self.old_attributes_checksum.clear();
+    }
+
+    pub fn has_old_attributes_checksum(&self) -> bool {
+        self.old_attributes_checksum.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_old_attributes_checksum(&mut self, v: super::playlist4meta::ListChecksum) {
+        self.old_attributes_checksum = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_old_attributes_checksum(&mut self) -> &mut super::playlist4meta::ListChecksum {
+        if self.old_attributes_checksum.is_none() {
+            self.old_attributes_checksum.set_default();
+        }
+        self.old_attributes_checksum.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_old_attributes_checksum(&mut self) -> super::playlist4meta::ListChecksum {
+        self.old_attributes_checksum.take().unwrap_or_else(|| super::playlist4meta::ListChecksum::new())
+    }
+}
+
+impl ::protobuf::Message for UpdateListAttributes {
+    fn is_initialized(&self) -> bool {
+        for v in &self.new_attributes {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.old_attributes {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.list_checksum {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.old_attributes_checksum {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.new_attributes)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.old_attributes)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.list_checksum)?;
+                },
+                4 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.old_attributes_checksum)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(ref v) = self.new_attributes.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.old_attributes.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.list_checksum.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.old_attributes_checksum.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(ref v) = self.new_attributes.as_ref() {
+            os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.old_attributes.as_ref() {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.list_checksum.as_ref() {
+            os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.old_attributes_checksum.as_ref() {
+            os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> UpdateListAttributes {
+        UpdateListAttributes::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ListAttributesPartialState>>(
+                    "new_attributes",
+                    |m: &UpdateListAttributes| { &m.new_attributes },
+                    |m: &mut UpdateListAttributes| { &mut m.new_attributes },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ListAttributesPartialState>>(
+                    "old_attributes",
+                    |m: &UpdateListAttributes| { &m.old_attributes },
+                    |m: &mut UpdateListAttributes| { &mut m.old_attributes },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListChecksum>>(
+                    "list_checksum",
+                    |m: &UpdateListAttributes| { &m.list_checksum },
+                    |m: &mut UpdateListAttributes| { &mut m.list_checksum },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::playlist4meta::ListChecksum>>(
+                    "old_attributes_checksum",
+                    |m: &UpdateListAttributes| { &m.old_attributes_checksum },
+                    |m: &mut UpdateListAttributes| { &mut m.old_attributes_checksum },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<UpdateListAttributes>(
+                    "UpdateListAttributes",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static UpdateListAttributes {
+        static mut instance: ::protobuf::lazy::Lazy<UpdateListAttributes> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const UpdateListAttributes,
+        };
+        unsafe {
+            instance.get(UpdateListAttributes::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for UpdateListAttributes {
+    fn clear(&mut self) {
+        self.new_attributes.clear();
+        self.old_attributes.clear();
+        self.list_checksum.clear();
+        self.old_attributes_checksum.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for UpdateListAttributes {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for UpdateListAttributes {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct Op {
+    // message fields
+    kind: ::std::option::Option<Op_Kind>,
+    add: ::protobuf::SingularPtrField<Add>,
+    rem: ::protobuf::SingularPtrField<Rem>,
+    mov: ::protobuf::SingularPtrField<Mov>,
+    update_item_attributes: ::protobuf::SingularPtrField<UpdateItemAttributes>,
+    update_list_attributes: ::protobuf::SingularPtrField<UpdateListAttributes>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a Op {
+    fn default() -> &'a Op {
+        <Op as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl Op {
+    pub fn new() -> Op {
+        ::std::default::Default::default()
+    }
+
+    // optional .Op.Kind kind = 1;
+
+
+    pub fn get_kind(&self) -> Op_Kind {
+        self.kind.unwrap_or(Op_Kind::KIND_UNKNOWN)
+    }
+    pub fn clear_kind(&mut self) {
+        self.kind = ::std::option::Option::None;
+    }
+
+    pub fn has_kind(&self) -> bool {
+        self.kind.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_kind(&mut self, v: Op_Kind) {
+        self.kind = ::std::option::Option::Some(v);
+    }
+
+    // optional .Add add = 2;
+
+
+    pub fn get_add(&self) -> &Add {
+        self.add.as_ref().unwrap_or_else(|| Add::default_instance())
+    }
+    pub fn clear_add(&mut self) {
+        self.add.clear();
+    }
+
+    pub fn has_add(&self) -> bool {
+        self.add.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_add(&mut self, v: Add) {
+        self.add = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_add(&mut self) -> &mut Add {
+        if self.add.is_none() {
+            self.add.set_default();
+        }
+        self.add.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_add(&mut self) -> Add {
+        self.add.take().unwrap_or_else(|| Add::new())
+    }
+
+    // optional .Rem rem = 3;
+
+
+    pub fn get_rem(&self) -> &Rem {
+        self.rem.as_ref().unwrap_or_else(|| Rem::default_instance())
+    }
+    pub fn clear_rem(&mut self) {
+        self.rem.clear();
+    }
+
+    pub fn has_rem(&self) -> bool {
+        self.rem.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_rem(&mut self, v: Rem) {
+        self.rem = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_rem(&mut self) -> &mut Rem {
+        if self.rem.is_none() {
+            self.rem.set_default();
+        }
+        self.rem.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_rem(&mut self) -> Rem {
+        self.rem.take().unwrap_or_else(|| Rem::new())
+    }
+
+    // optional .Mov mov = 4;
+
+
+    pub fn get_mov(&self) -> &Mov {
+        self.mov.as_ref().unwrap_or_else(|| Mov::default_instance())
+    }
+    pub fn clear_mov(&mut self) {
+        self.mov.clear();
+    }
+
+    pub fn has_mov(&self) -> bool {
+        self.mov.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_mov(&mut self, v: Mov) {
+        self.mov = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_mov(&mut self) -> &mut Mov {
+        if self.mov.is_none() {
+            self.mov.set_default();
+        }
+        self.mov.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_mov(&mut self) -> Mov {
+        self.mov.take().unwrap_or_else(|| Mov::new())
+    }
+
+    // optional .UpdateItemAttributes update_item_attributes = 5;
+
+
+    pub fn get_update_item_attributes(&self) -> &UpdateItemAttributes {
+        self.update_item_attributes.as_ref().unwrap_or_else(|| UpdateItemAttributes::default_instance())
+    }
+    pub fn clear_update_item_attributes(&mut self) {
+        self.update_item_attributes.clear();
+    }
+
+    pub fn has_update_item_attributes(&self) -> bool {
+        self.update_item_attributes.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_update_item_attributes(&mut self, v: UpdateItemAttributes) {
+        self.update_item_attributes = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_update_item_attributes(&mut self) -> &mut UpdateItemAttributes {
+        if self.update_item_attributes.is_none() {
+            self.update_item_attributes.set_default();
+        }
+        self.update_item_attributes.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_update_item_attributes(&mut self) -> UpdateItemAttributes {
+        self.update_item_attributes.take().unwrap_or_else(|| UpdateItemAttributes::new())
+    }
+
+    // optional .UpdateListAttributes update_list_attributes = 6;
+
+
+    pub fn get_update_list_attributes(&self) -> &UpdateListAttributes {
+        self.update_list_attributes.as_ref().unwrap_or_else(|| UpdateListAttributes::default_instance())
+    }
+    pub fn clear_update_list_attributes(&mut self) {
+        self.update_list_attributes.clear();
+    }
+
+    pub fn has_update_list_attributes(&self) -> bool {
+        self.update_list_attributes.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_update_list_attributes(&mut self, v: UpdateListAttributes) {
+        self.update_list_attributes = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_update_list_attributes(&mut self) -> &mut UpdateListAttributes {
+        if self.update_list_attributes.is_none() {
+            self.update_list_attributes.set_default();
+        }
+        self.update_list_attributes.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_update_list_attributes(&mut self) -> UpdateListAttributes {
+        self.update_list_attributes.take().unwrap_or_else(|| UpdateListAttributes::new())
+    }
+}
+
+impl ::protobuf::Message for Op {
+    fn is_initialized(&self) -> bool {
+        for v in &self.add {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.rem {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.mov {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.update_item_attributes {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.update_list_attributes {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_proto2_enum_with_unknown_fields_into(wire_type, is, &mut self.kind, 1, &mut self.unknown_fields)?
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.add)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.rem)?;
+                },
+                4 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.mov)?;
+                },
+                5 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.update_item_attributes)?;
+                },
+                6 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.update_list_attributes)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if let Some(v) = self.kind {
+            my_size += ::protobuf::rt::enum_size(1, v);
+        }
+        if let Some(ref v) = self.add.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.rem.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.mov.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.update_item_attributes.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.update_list_attributes.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        if let Some(v) = self.kind {
+            os.write_enum(1, v.value())?;
+        }
+        if let Some(ref v) = self.add.as_ref() {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.rem.as_ref() {
+            os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.mov.as_ref() {
+            os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.update_item_attributes.as_ref() {
+            os.write_tag(5, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.update_list_attributes.as_ref() {
+            os.write_tag(6, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> Op {
+        Op::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum<Op_Kind>>(
+                    "kind",
+                    |m: &Op| { &m.kind },
+                    |m: &mut Op| { &mut m.kind },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Add>>(
+                    "add",
+                    |m: &Op| { &m.add },
+                    |m: &mut Op| { &mut m.add },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Rem>>(
+                    "rem",
+                    |m: &Op| { &m.rem },
+                    |m: &mut Op| { &mut m.rem },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Mov>>(
+                    "mov",
+                    |m: &Op| { &m.mov },
+                    |m: &mut Op| { &mut m.mov },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<UpdateItemAttributes>>(
+                    "update_item_attributes",
+                    |m: &Op| { &m.update_item_attributes },
+                    |m: &mut Op| { &mut m.update_item_attributes },
+                ));
+                fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<UpdateListAttributes>>(
+                    "update_list_attributes",
+                    |m: &Op| { &m.update_list_attributes },
+                    |m: &mut Op| { &mut m.update_list_attributes },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<Op>(
+                    "Op",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static Op {
+        static mut instance: ::protobuf::lazy::Lazy<Op> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const Op,
+        };
+        unsafe {
+            instance.get(Op::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for Op {
+    fn clear(&mut self) {
+        self.kind = ::std::option::Option::None;
+        self.add.clear();
+        self.rem.clear();
+        self.mov.clear();
+        self.update_item_attributes.clear();
+        self.update_list_attributes.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for Op {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for Op {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+#[derive(Clone,PartialEq,Eq,Debug,Hash)]
+pub enum Op_Kind {
+    KIND_UNKNOWN = 0,
+    ADD = 2,
+    REM = 3,
+    MOV = 4,
+    UPDATE_ITEM_ATTRIBUTES = 5,
+    UPDATE_LIST_ATTRIBUTES = 6,
+}
+
+impl ::protobuf::ProtobufEnum for Op_Kind {
+    fn value(&self) -> i32 {
+        *self as i32
+    }
+
+    fn from_i32(value: i32) -> ::std::option::Option<Op_Kind> {
+        match value {
+            0 => ::std::option::Option::Some(Op_Kind::KIND_UNKNOWN),
+            2 => ::std::option::Option::Some(Op_Kind::ADD),
+            3 => ::std::option::Option::Some(Op_Kind::REM),
+            4 => ::std::option::Option::Some(Op_Kind::MOV),
+            5 => ::std::option::Option::Some(Op_Kind::UPDATE_ITEM_ATTRIBUTES),
+            6 => ::std::option::Option::Some(Op_Kind::UPDATE_LIST_ATTRIBUTES),
+            _ => ::std::option::Option::None
+        }
+    }
+
+    fn values() -> &'static [Self] {
+        static values: &'static [Op_Kind] = &[
+            Op_Kind::KIND_UNKNOWN,
+            Op_Kind::ADD,
+            Op_Kind::REM,
+            Op_Kind::MOV,
+            Op_Kind::UPDATE_ITEM_ATTRIBUTES,
+            Op_Kind::UPDATE_LIST_ATTRIBUTES,
+        ];
+        values
+    }
+
+    fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::EnumDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                ::protobuf::reflect::EnumDescriptor::new("Op_Kind", file_descriptor_proto())
+            })
+        }
+    }
+}
+
+impl ::std::marker::Copy for Op_Kind {
+}
+
+impl ::std::default::Default for Op_Kind {
+    fn default() -> Self {
+        Op_Kind::KIND_UNKNOWN
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for Op_Kind {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor())
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct OpList {
+    // message fields
+    ops: ::protobuf::RepeatedField<Op>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a OpList {
+    fn default() -> &'a OpList {
+        <OpList as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl OpList {
+    pub fn new() -> OpList {
+        ::std::default::Default::default()
+    }
+
+    // repeated .Op ops = 1;
+
+
+    pub fn get_ops(&self) -> &[Op] {
+        &self.ops
+    }
+    pub fn clear_ops(&mut self) {
+        self.ops.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_ops(&mut self, v: ::protobuf::RepeatedField<Op>) {
+        self.ops = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_ops(&mut self) -> &mut ::protobuf::RepeatedField<Op> {
+        &mut self.ops
+    }
+
+    // Take field
+    pub fn take_ops(&mut self) -> ::protobuf::RepeatedField<Op> {
+        ::std::mem::replace(&mut self.ops, ::protobuf::RepeatedField::new())
+    }
+}
+
+impl ::protobuf::Message for OpList {
+    fn is_initialized(&self) -> bool {
+        for v in &self.ops {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.ops)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        for value in &self.ops {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
+        for v in &self.ops {
+            os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &::std::any::Any {
+        self as &::std::any::Any
+    }
+    fn as_any_mut(&mut self) -> &mut ::std::any::Any {
+        self as &mut ::std::any::Any
+    }
+    fn into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> OpList {
+        OpList::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
+        };
+        unsafe {
+            descriptor.get(|| {
+                let mut fields = ::std::vec::Vec::new();
+                fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Op>>(
+                    "ops",
+                    |m: &OpList| { &m.ops },
+                    |m: &mut OpList| { &mut m.ops },
+                ));
+                ::protobuf::reflect::MessageDescriptor::new::<OpList>(
+                    "OpList",
+                    fields,
+                    file_descriptor_proto()
+                )
+            })
+        }
+    }
+
+    fn default_instance() -> &'static OpList {
+        static mut instance: ::protobuf::lazy::Lazy<OpList> = ::protobuf::lazy::Lazy {
+            lock: ::protobuf::lazy::ONCE_INIT,
+            ptr: 0 as *const OpList,
+        };
+        unsafe {
+            instance.get(OpList::new)
+        }
+    }
+}
+
+impl ::protobuf::Clear for OpList {
+    fn clear(&mut self) {
+        self.ops.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for OpList {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for OpList {
+    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
+        ::protobuf::reflect::ProtobufValueRef::Message(self)
+    }
+}
+
+static file_descriptor_proto_data: &'static [u8] = b"\
+    \n\x12playlist4ops.proto\x12\0\"\x83\x01\n\x03Add\x12\x13\n\tfromIndex\
+    \x18\x01\x20\x01(\x05B\0\x12\x16\n\x05items\x18\x02\x20\x03(\x0b2\x05.It\
+    emB\0\x12&\n\rlist_checksum\x18\x03\x20\x01(\x0b2\r.ListChecksumB\0\x12\
+    \x11\n\x07addLast\x18\x04\x20\x01(\x08B\0\x12\x12\n\x08addFirst\x18\x05\
+    \x20\x01(\x08B\0:\0\"\xd5\x01\n\x03Rem\x12\x13\n\tfromIndex\x18\x01\x20\
+    \x01(\x05B\0\x12\x10\n\x06length\x18\x02\x20\x01(\x05B\0\x12\x16\n\x05it\
+    ems\x18\x03\x20\x03(\x0b2\x05.ItemB\0\x12&\n\rlist_checksum\x18\x04\x20\
+    \x01(\x0b2\r.ListChecksumB\0\x12'\n\x0eitems_checksum\x18\x05\x20\x01(\
+    \x0b2\r.ListChecksumB\0\x12&\n\ruris_checksum\x18\x06\x20\x01(\x0b2\r.Li\
+    stChecksumB\0\x12\x14\n\nitemsAsKey\x18\x07\x20\x01(\x08B\0:\0\"\xba\x01\
+    \n\x03Mov\x12\x13\n\tfromIndex\x18\x01\x20\x01(\x05B\0\x12\x10\n\x06leng\
+    th\x18\x02\x20\x01(\x05B\0\x12\x11\n\x07toIndex\x18\x03\x20\x01(\x05B\0\
+    \x12&\n\rlist_checksum\x18\x04\x20\x01(\x0b2\r.ListChecksumB\0\x12'\n\
+    \x0eitems_checksum\x18\x05\x20\x01(\x0b2\r.ListChecksumB\0\x12&\n\ruris_\
+    checksum\x18\x06\x20\x01(\x0b2\r.ListChecksumB\0:\0\"\x82\x03\n\x1aItemA\
+    ttributesPartialState\x12!\n\x06values\x18\x01\x20\x01(\x0b2\x0f.ItemAtt\
+    ributesB\0\x12A\n\x08no_value\x18\x02\x20\x03(\x0e2-.ItemAttributesParti\
+    alState.ItemAttributeKindB\0\"\xfb\x01\n\x11ItemAttributeKind\x12\x10\n\
+    \x0cITEM_UNKNOWN\x10\0\x12\x11\n\rITEM_ADDED_BY\x10\x01\x12\x12\n\x0eITE\
+    M_TIMESTAMP\x10\x02\x12\x10\n\x0cITEM_MESSAGE\x10\x03\x12\r\n\tITEM_SEEN\
+    \x10\x04\x12\x17\n\x13ITEM_DOWNLOAD_COUNT\x10\x05\x12\x18\n\x14ITEM_DOWN\
+    LOAD_FORMAT\x10\x06\x12\x18\n\x14ITEM_SEVENDIGITAL_ID\x10\x07\x12\x1a\n\
+    \x16ITEM_SEVENDIGITAL_LEFT\x10\x08\x12\x10\n\x0cITEM_SEEN_AT\x10\t\x12\
+    \x0f\n\x0bITEM_PUBLIC\x10\n\x1a\0:\0\"\xd1\x02\n\x1aListAttributesPartia\
+    lState\x12!\n\x06values\x18\x01\x20\x01(\x0b2\x0f.ListAttributesB\0\x12A\
+    \n\x08no_value\x18\x02\x20\x03(\x0e2-.ListAttributesPartialState.ListAtt\
+    ributeKindB\0\"\xca\x01\n\x11ListAttributeKind\x12\x10\n\x0cLIST_UNKNOWN\
+    \x10\0\x12\r\n\tLIST_NAME\x10\x01\x12\x14\n\x10LIST_DESCRIPTION\x10\x02\
+    \x12\x10\n\x0cLIST_PICTURE\x10\x03\x12\x16\n\x12LIST_COLLABORATIVE\x10\
+    \x04\x12\x14\n\x10LIST_PL3_VERSION\x10\x05\x12\x19\n\x15LIST_DELETED_BY_\
+    OWNER\x10\x06\x12!\n\x1dLIST_RESTRICTED_COLLABORATIVE\x10\x07\x1a\0:\0\"\
+    \xf1\x01\n\x14UpdateItemAttributes\x12\x0f\n\x05index\x18\x01\x20\x01(\
+    \x05B\0\x125\n\x0enew_attributes\x18\x02\x20\x01(\x0b2\x1b.ItemAttribute\
+    sPartialStateB\0\x125\n\x0eold_attributes\x18\x03\x20\x01(\x0b2\x1b.Item\
+    AttributesPartialStateB\0\x12&\n\rlist_checksum\x18\x04\x20\x01(\x0b2\r.\
+    ListChecksumB\0\x120\n\x17old_attributes_checksum\x18\x05\x20\x01(\x0b2\
+    \r.ListChecksumB\0:\0\"\xe0\x01\n\x14UpdateListAttributes\x125\n\x0enew_\
+    attributes\x18\x01\x20\x01(\x0b2\x1b.ListAttributesPartialStateB\0\x125\
+    \n\x0eold_attributes\x18\x02\x20\x01(\x0b2\x1b.ListAttributesPartialStat\
+    eB\0\x12&\n\rlist_checksum\x18\x03\x20\x01(\x0b2\r.ListChecksumB\0\x120\
+    \n\x17old_attributes_checksum\x18\x04\x20\x01(\x0b2\r.ListChecksumB\0:\0\
+    \"\xc0\x02\n\x02Op\x12\x18\n\x04kind\x18\x01\x20\x01(\x0e2\x08.Op.KindB\
+    \0\x12\x13\n\x03add\x18\x02\x20\x01(\x0b2\x04.AddB\0\x12\x13\n\x03rem\
+    \x18\x03\x20\x01(\x0b2\x04.RemB\0\x12\x13\n\x03mov\x18\x04\x20\x01(\x0b2\
+    \x04.MovB\0\x127\n\x16update_item_attributes\x18\x05\x20\x01(\x0b2\x15.U\
+    pdateItemAttributesB\0\x127\n\x16update_list_attributes\x18\x06\x20\x01(\
+    \x0b2\x15.UpdateListAttributesB\0\"m\n\x04Kind\x12\x10\n\x0cKIND_UNKNOWN\
+    \x10\0\x12\x07\n\x03ADD\x10\x02\x12\x07\n\x03REM\x10\x03\x12\x07\n\x03MO\
+    V\x10\x04\x12\x1a\n\x16UPDATE_ITEM_ATTRIBUTES\x10\x05\x12\x1a\n\x16UPDAT\
+    E_LIST_ATTRIBUTES\x10\x06\x1a\0:\0\"\x1e\n\x06OpList\x12\x12\n\x03ops\
+    \x18\x01\x20\x03(\x0b2\x03.OpB\0:\0B\0b\x06proto2\
+";
+
+static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy {
+    lock: ::protobuf::lazy::ONCE_INIT,
+    ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto,
+};
+
+fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
+    ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()
+}
+
+pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
+    unsafe {
+        file_descriptor_proto_lazy.get(|| {
+            parse_descriptor_proto()
+        })
+    }
+}