throws IOException, AccessDeniedException, SlobNotFoundException {
Preconditions.checkNotNull(convObjectId, "Null convObjectId");
Preconditions.checkNotNull(clientId, "Null clientId");
Pair<ConnectResult, String> convPair = convStore.connect(convObjectId, clientId);
ConnectResult convResult = convPair.getFirst();
String rawConvSnapshot = convPair.getSecond();
log(convObjectId, convResult);
WaveletName convWaveletName = IdHack.convWaveletNameFromConvObjectId(convObjectId);
// The most recent version of wavelet to get list of documents from.
WaveletDataImpl convWavelet = deserializeWavelet(convWaveletName, rawConvSnapshot);
long convVersion = convResult.getVersion();
Assert.check(convVersion == convWavelet.getVersion(),
"ConnectResult revision %s does not match wavelet version %s",
convVersion, convWavelet.getVersion());
if (!enableUdw) {
return waveWithoutUdw(convObjectId, convResult, convWavelet);
} else {
// Now we go and load some of the history in order to render diffs.
// For fully read or unread blips, we don't need to load any history.
// So the approach here is to find all the blips that are partially
// read, and get the smallest version.
// TODO(ohler): This should be getOrCreateAndConnect(), so that we can avoid
// reconstructing the state of the wavelet that we just created. But
// snapshot caching would help with this as well, so we should probably do
// that first.
SlobId udwId = waveletCreator.getOrCreateUdw(convObjectId);
Pair<ConnectResult, String> udwPair;
try {
udwPair = udwStore.connect(udwId, clientId);
} catch (SlobNotFoundException e) {
throw new RuntimeException("UDW disappeared right after getOrCreateUdw(): " + udwId);
}
ConnectResult udwResult = udwPair.getFirst();
WaveletName udwWaveletName = IdHack.udwWaveletNameFromConvObjectIdAndUdwObjectId(
convObjectId, udwId);
WaveletDataImpl udw = deserializeWavelet(udwWaveletName, udwPair.getSecond());
WalkaroundWaveletSnapshot udwSnapshot = serializer.createWaveletMessage(udw);
LoadedUdw loadedUdw = new LoadedUdw(udwId, udwResult, udwSnapshot);