gt: 		if (myInterface == null) {
context: /*
   * Copyright (C) 2007-2014 Geometer Plus <contact@geometerplus.com>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   * 02110-1301, USA.
   */
  
  package org.geometerplus.android.fbreader.libraryService;
  
  import android.content.BroadcastReceiver;
  import android.content.ComponentName;
  import android.content.Context;
  import android.content.Intent;
  import android.content.IntentFilter;
  import android.content.ServiceConnection;
  import android.os.IBinder;
  import android.os.RemoteException;
  
  import org.geometerplus.android.fbreader.api.FBReaderIntents;
  import org.geometerplus.fbreader.book.AbstractBookCollection;
  import org.geometerplus.fbreader.book.Author;
  import org.geometerplus.fbreader.book.Book;
  import org.geometerplus.fbreader.book.BookEvent;
  import org.geometerplus.fbreader.book.BookQuery;
  import org.geometerplus.fbreader.book.Bookmark;
  import org.geometerplus.fbreader.book.BookmarkQuery;
  import org.geometerplus.fbreader.book.Filter;
  import org.geometerplus.fbreader.book.HighlightingStyle;
  import org.geometerplus.fbreader.book.SerializerUtil;
  import org.geometerplus.fbreader.book.Tag;
  import org.geometerplus.fbreader.book.UID;
  import org.geometerplus.zlibrary.core.filesystem.ZLFile;
  import org.geometerplus.zlibrary.core.image.ZLImage;
  import org.geometerplus.zlibrary.core.options.Config;
  import org.geometerplus.zlibrary.text.view.ZLTextFixedPosition;
  import org.geometerplus.zlibrary.text.view.ZLTextPosition;
  import org.geometerplus.zlibrary.ui.android.image.ZLBitmapImage;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.LinkedList;
  import java.util.List;
  
  public class BookCollectionShadow extends AbstractBookCollection implements ServiceConnection {
  	private volatile Context myContext;
  	private volatile LibraryInterface myInterface;
  	private final List<Runnable> myOnBindActions = new LinkedList<Runnable>();
  
  	private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
  		public void onReceive(Context context, Intent intent) {
  			if (!hasListeners()) {
  				return;
  			}
  
  			try {
  				final String type = intent.getStringExtra("type");
  				if (LibraryService.BOOK_EVENT_ACTION.equals(intent.getAction())) {
  					final Book book = SerializerUtil.deserializeBook(intent.getStringExtra("book"));
  					fireBookEvent(BookEvent.valueOf(type), book);
  				} else {
  					fireBuildEvent(Status.valueOf(type));
  				}
  			} catch (Exception e) {
  				// ignore
  			}
  		}
  	};
  
  	public synchronized void bindToService(Context context, Runnable onBindAction) {
  		if (myInterface != null && myContext == context) {
  			if (onBindAction != null) {
  				Config.Instance().runOnConnect(onBindAction);
  			}
  		} else {
  			if (onBindAction != null) {
  				myOnBindActions.add(onBindAction);
  			}
  			context.bindService(
  				FBReaderIntents.internalIntent(FBReaderIntents.Action.LIBRARY_SERVICE),
  				this,
  				LibraryService.BIND_AUTO_CREATE
  			);
  			myContext = context;
  		}
  	}
  
  	public synchronized void unbind() {
  		if (myContext != null && myInterface != null) {
  			try {
  				myContext.unregisterReceiver(myReceiver);
  			} catch (IllegalArgumentException e) {
  				// called before regisration, that's ok
  			} catch (Exception e) {
  				e.printStackTrace();
  			}
  			try {
  				myContext.unbindService(this);
  			} catch (Exception e) {
  				e.printStackTrace();
  			}
  			myInterface = null;
  			myContext = null;
  		}
  	}
  
  	public synchronized void reset(boolean force) {
  		if (myInterface != null) {
  			try {
  				myInterface.reset(force);
  			} catch (RemoteException e) {
  			}
  		}
  	}
  
  	public synchronized int size() {
  		if (myInterface == null) {
  			return 0;
  		}
  		try {
  			return myInterface.size();
  		} catch (RemoteException e) {
  			return 0;
  		}
  	}
  
  	public synchronized Status status() {
  		if (myInterface == null) {
  			return Status.NotStarted;
  		}
  		try {
  			return Status.valueOf(myInterface.status());
  		} catch (Throwable t) {
  			return Status.NotStarted;
  		}
  	}
  
  	public synchronized List<Book> books(BookQuery query) {
  		if (myInterface == null) {
  			return Collections.emptyList();
  		}
  		try {
  			return SerializerUtil.deserializeBookList(myInterface.books(SerializerUtil.serialize(query)));
  		} catch (RemoteException e) {
  			return Collections.emptyList();
  		}
  	}
  
  	public synchronized boolean hasBooks(Filter filter) {
  		if (myInterface == null) {
  			return false;
  		}
  		try {
  			return myInterface.hasBooks(SerializerUtil.serialize(new BookQuery(filter, 1)));
  		} catch (RemoteException e) {
  			return false;
  		}
  	}
  
  	public synchronized List<Book> recentBooks() {
  		if (myInterface == null) {
  			return Collections.emptyList();
  		}
  		try {
  			return SerializerUtil.deserializeBookList(myInterface.recentBooks());
  		} catch (RemoteException e) {
  			return Collections.emptyList();
  		}
  	}
  
  	public synchronized Book getRecentBook(int index) {
  		if (myInterface == null) {
  			return null;
  		}
  		try {
  			return SerializerUtil.deserializeBook(myInterface.getRecentBook(index));
  		} catch (RemoteException e) {
  			e.printStackTrace();
  			return null;
  		}
  	}
  
  	public synchronized Book getBookByFile(ZLFile file) {
  		if (myInterface == null) {
  			return null;
  		}
  		try {
  			return SerializerUtil.deserializeBook(myInterface.getBookByFile(file.getPath()));
  		} catch (RemoteException e) {
  			return null;
  		}
  	}
  
  	public synchronized Book getBookById(long id) {
  		if (myInterface == null) {
  			return null;
  		}
  		try {
  			return SerializerUtil.deserializeBook(myInterface.getBookById(id));
  		} catch (RemoteException e) {
  			return null;
  		}
  	}
  
  	public synchronized Book getBookByUid(UID uid) {
  