/*
 * Copyright (C) 2008 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.common.util.concurrent;
public class FuturesTest_gwt extends com.google.gwt.junit.client.GWTTestCase {
@Override public String getModuleName() {
  return "com.google.common.util.concurrent.testModule";
}
public void testAllAsList() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_cancelled() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_cancelled();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_doneFutures() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_doneFutures();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_emptyArray() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_emptyArray();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_emptyList() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_emptyList();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_error() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_error();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_failure() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_failure();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_immediateFailure() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_immediateFailure();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_logging_error() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_logging_error();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_logging_exception() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_logging_exception();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_logging_multipleExceptions_alreadyDone() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_logging_multipleExceptions_alreadyDone();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_logging_multipleExceptions_doneLater() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_logging_multipleExceptions_doneLater();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_logging_same_cause() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_logging_same_cause();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_logging_same_exception() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_logging_same_exception();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_logging_seenExceptionUpdateCancelRace() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_logging_seenExceptionUpdateCancelRace();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_logging_seenExceptionUpdateRace() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_logging_seenExceptionUpdateRace();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_resultCancelled() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_resultCancelled();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_resultCancelledInterrupted_withSecondaryListFuture() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_resultCancelledInterrupted_withSecondaryListFuture();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_resultCancelled_withSecondaryListFuture() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_resultCancelled_withSecondaryListFuture();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_resultInterrupted() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_resultInterrupted();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testAllAsList_singleFailure() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testAllAsList_singleFailure();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCancellingADelegatePropagates() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCancellingADelegatePropagates();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCancellingAllDelegatesIsNotQuadratic() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCancellingAllDelegatesIsNotQuadratic();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_ErrorAfterCancellation() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_ErrorAfterCancellation();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_ExceptionAfterCancellation() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_ExceptionAfterCancellation();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_Throwable() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_Throwable();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_fallbackGeneratesCheckedException() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_fallbackGeneratesCheckedException();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_fallbackGeneratesError() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_fallbackGeneratesError();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_fallbackGeneratesRuntimeException() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_fallbackGeneratesRuntimeException();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_fallbackNotReady() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_fallbackNotReady();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_fallbackReturnsCheckedException() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_fallbackReturnsCheckedException();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_fallbackReturnsRuntimeException() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_fallbackReturnsRuntimeException();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_futureToString() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_futureToString();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_getThrowsError() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_getThrowsError();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_getThrowsRuntimeException() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_getThrowsRuntimeException();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_inputDoesNotRaiseException() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_inputDoesNotRaiseException();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_inputRaisesException() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_inputRaisesException();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_listenerThrowsError() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_listenerThrowsError();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_nullInsteadOfFuture() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_nullInsteadOfFuture();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_rejectionPropagatesToOutput() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_rejectionPropagatesToOutput();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_resultCancelledBeforeFallback() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_resultCancelledBeforeFallback();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatchingAsync_resultInterruptedBeforeFallback() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatchingAsync_resultInterruptedBeforeFallback();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatching_ErrorAfterCancellation() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatching_ErrorAfterCancellation();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatching_ExceptionAfterCancellation() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatching_ExceptionAfterCancellation();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatching_Throwable() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatching_Throwable();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatching_fallbackGeneratesError() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatching_fallbackGeneratesError();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatching_fallbackGeneratesRuntimeException() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatching_fallbackGeneratesRuntimeException();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatching_getThrowsError() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatching_getThrowsError();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatching_getThrowsRuntimeException() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatching_getThrowsRuntimeException();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatching_inputDoesNotRaiseException() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatching_inputDoesNotRaiseException();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatching_inputRaisesException() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatching_inputRaisesException();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatching_listenerThrowsError() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatching_listenerThrowsError();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatching_rejectionPropagatesToOutput() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatching_rejectionPropagatesToOutput();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatching_resultCancelledBeforeFallback() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatching_resultCancelledBeforeFallback();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCatching_resultInterruptedBeforeFallback() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCatching_resultInterruptedBeforeFallback();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCompletionOrder() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCompletionOrder();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCompletionOrderExceptionThrown() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCompletionOrderExceptionThrown();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCompletionOrderFutureCancelled() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCompletionOrderFutureCancelled();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCompletionOrderFutureInterruption() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCompletionOrderFutureInterruption();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testCompletionOrderMixedBagOTypes() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testCompletionOrderMixedBagOTypes();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testImmediateCancelledFutureBasic() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testImmediateCancelledFutureBasic();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testImmediateFailedFuture() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testImmediateFailedFuture();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testImmediateFailedFuture_cancellationException() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testImmediateFailedFuture_cancellationException();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testImmediateFuture() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testImmediateFuture();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testNonCancellationPropagating_delegateCancelled() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testNonCancellationPropagating_delegateCancelled();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testNonCancellationPropagating_doesNotPropagate() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testNonCancellationPropagating_doesNotPropagate();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testNonCancellationPropagating_failure() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testNonCancellationPropagating_failure();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testNonCancellationPropagating_successful() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testNonCancellationPropagating_successful();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testSubmitAsync_asyncCallable_error() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testSubmitAsync_asyncCallable_error();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testSubmitAsync_asyncCallable_nullInsteadOfFuture() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testSubmitAsync_asyncCallable_nullInsteadOfFuture();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testSuccessfulAsList() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testSuccessfulAsList();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testSuccessfulAsList_cancelled() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testSuccessfulAsList_cancelled();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testSuccessfulAsList_emptyArray() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testSuccessfulAsList_emptyArray();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testSuccessfulAsList_emptyList() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testSuccessfulAsList_emptyList();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testSuccessfulAsList_logging_error() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testSuccessfulAsList_logging_error();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testSuccessfulAsList_logging_exception() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testSuccessfulAsList_logging_exception();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testSuccessfulAsList_mixed() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testSuccessfulAsList_mixed();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testSuccessfulAsList_partialFailure() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testSuccessfulAsList_partialFailure();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testSuccessfulAsList_resultCancelled() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testSuccessfulAsList_resultCancelled();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testSuccessfulAsList_resultCancelledRacingInputDone() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testSuccessfulAsList_resultCancelledRacingInputDone();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testSuccessfulAsList_resultInterrupted() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testSuccessfulAsList_resultInterrupted();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testSuccessfulAsList_totalFailure() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testSuccessfulAsList_totalFailure();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_ErrorAfterCancellation() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_ErrorAfterCancellation();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_ExceptionAfterCancellation() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_ExceptionAfterCancellation();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_asyncFunction_error() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_asyncFunction_error();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_asyncFunction_nullInsteadOfFuture() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_asyncFunction_nullInsteadOfFuture();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_cancelPropagatesToAsyncOutput() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_cancelPropagatesToAsyncOutput();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_cancelPropagatesToInput() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_cancelPropagatesToInput();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_genericsHierarchy_AsyncFunction() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_genericsHierarchy_AsyncFunction();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_genericsWildcard_AsyncFunction() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_genericsWildcard_AsyncFunction();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_getThrowsError() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_getThrowsError();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_getThrowsRuntimeException() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_getThrowsRuntimeException();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_inputCancelButNotInterruptPropagatesToOutput() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_inputCancelButNotInterruptPropagatesToOutput();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_interruptPropagatesToAsyncOutput() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_interruptPropagatesToAsyncOutput();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_interruptPropagatesToInput() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_interruptPropagatesToInput();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_listenerThrowsError() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_listenerThrowsError();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformAsync_rejectionPropagatesToOutput() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformAsync_rejectionPropagatesToOutput();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransformValueRemainsMemoized() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransformValueRemainsMemoized();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransform_ErrorAfterCancellation() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransform_ErrorAfterCancellation();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransform_ExceptionAfterCancellation() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransform_ExceptionAfterCancellation();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransform_Executor() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransform_Executor();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransform_genericsHierarchy() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransform_genericsHierarchy();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransform_genericsNull() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransform_genericsNull();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransform_getThrowsError() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransform_getThrowsError();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransform_getThrowsRuntimeException() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransform_getThrowsRuntimeException();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransform_listenerThrowsError() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransform_listenerThrowsError();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testTransform_rejectionPropagatesToOutput() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testTransform_rejectionPropagatesToOutput();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testWhenAllComplete_asyncError() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testWhenAllComplete_asyncError();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testWhenAllComplete_asyncResult() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testWhenAllComplete_asyncResult();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testWhenAllComplete_runnableError() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testWhenAllComplete_runnableError();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testWhenAllComplete_runnableResult() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testWhenAllComplete_runnableResult();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testWhenAllComplete_wildcard() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testWhenAllComplete_wildcard();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}

public void testWhenAllSucceed() throws Exception {
  com.google.common.util.concurrent.FuturesTest testCase = new com.google.common.util.concurrent.FuturesTest();
  testCase.setUp();
  Throwable failure = null;
  try {
    testCase.testWhenAllSucceed();
  } catch (Throwable t) {
    failure = t;
  }
  try {
    testCase.tearDown();
  } catch (Throwable t) {
    if (failure == null) {
      failure = t;
    }
  }
  if (failure instanceof Exception) {
    throw (Exception) failure;
  }
  if (failure instanceof Error) {
    throw (Error) failure;
  }
  if (failure != null) {
    throw new RuntimeException(failure);
  }
}
}
