CheckedProviderMethodsModuleTest.java revision b7a02b02d81c830d148355c90bc309bcd66fb592
14d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com/** 24d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com * Copyright (C) 2009 Google Inc. 34d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com * 44d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com * Licensed under the Apache License, Version 2.0 (the "License"); 54d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com * you may not use this file except in compliance with the License. 64d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com * You may obtain a copy of the License at 74d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com * 84d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com * http://www.apache.org/licenses/LICENSE-2.0 94d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com * 104d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com * Unless required by applicable law or agreed to in writing, software 114d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com * distributed under the License is distributed on an "AS IS" BASIS, 124d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com * See the License for the specific language governing permissions and 144d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com * limitations under the License. 154d93ce63450f6e58c44b0a8ef2143593fc08df86sberlin@gmail.com */ 16ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 17ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.compackage com.google.inject.throwingproviders; 18ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 19ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport com.google.inject.AbstractModule; 20ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport com.google.inject.BindingAnnotation; 21ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport com.google.inject.Exposed; 22ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport com.google.inject.Guice; 23ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport com.google.inject.Injector; 24ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport com.google.inject.Key; 25ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport com.google.inject.PrivateModule; 26ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport com.google.inject.Provides; 27ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport com.google.inject.TypeLiteral; 28ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport com.google.inject.name.Named; 29ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport com.google.inject.name.Names; 30ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 31ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport junit.framework.TestCase; 32ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 33ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport java.lang.annotation.Retention; 34ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport java.lang.annotation.RetentionPolicy; 35ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport java.net.BindException; 36ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.comimport java.rmi.RemoteException; 37ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 38ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com/** 39ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com * Test methods for {@link CheckedProviderMethodsModule}. 40ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com */ 41ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.compublic class CheckedProviderMethodsModuleTest extends TestCase { 42ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 43ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com private final TypeLiteral<RpcProvider<String>> rpcProviderOfString 44ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com = new TypeLiteral<RpcProvider<String>>() { }; 45ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com private final TypeLiteral<RpcProvider<Integer>> rpcProviderOfInteger 46ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com = new TypeLiteral<RpcProvider<Integer>>() { }; 47ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com private final TypeLiteral<RpcProvider<Long>> rpcProviderOfLong 48ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com = new TypeLiteral<RpcProvider<Long>>() { }; 49ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com private final TypeLiteral<RpcProvider<Float>> rpcProviderOfFloat 50ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com = new TypeLiteral<RpcProvider<Float>>() { }; 51ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com private final TypeLiteral<RpcProvider<Pair<Double, String>>> rpcProviderOfPair 52ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com = new TypeLiteral<RpcProvider<Pair<Double, String>>>() { }; 53ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 54ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com private final TestScope testScope = new TestScope(); 55ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 56ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com interface RpcProvider<T> extends CheckedProvider<T> { 57ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com T get() throws RemoteException, BindException; 58ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 59ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 60ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com @Retention(RetentionPolicy.RUNTIME) 61ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com @BindingAnnotation 62ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com @interface TestAnnotation { 63ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 64ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 65ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com class TestModule extends AbstractModule { 66ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 67ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com private int nextIntToReturn = 100; 68ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 69ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com @Override 70ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com protected void configure() { 71ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com bindScope(TestScope.Scoped.class, testScope); 72ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com install(ThrowingProviderBinder.forModule(this)); 73ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com install(new TestPrivateModule()); 74ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 75ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 76ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com @CheckedProvides(RpcProvider.class) 77ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com String getSomeStringFromServer() { 78ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com return "Works"; 79ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 80ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 81ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com @CheckedProvides(RpcProvider.class) @TestScope.Scoped 82ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com int getSomeIntegerFromServer() { 83ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com return nextIntToReturn; 84ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 85ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 86ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com @CheckedProvides(RpcProvider.class) @TestAnnotation 87ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com long getSomeLongFromServer() { 88ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com return 0xffL; 89ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 90ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 91ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com @Provides 92ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com double getSomeDouble() { 93ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com return 2.0d; 94ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 95ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 96ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com @CheckedProvides(RpcProvider.class) 97ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com Pair<Double, String> getSomePair(Double input) { 98ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com return new Pair<Double, String>(input * 2, "foo"); 99ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 100ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 101ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com @CheckedProvides(RpcProvider.class) 102ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com float getFloat() throws BindException { 103ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com throw new BindException("foo"); 104ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 105ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 106ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com void setNextIntToReturn(int next) { 107ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com nextIntToReturn = next; 108ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 109ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 110ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 111ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com class TestPrivateModule extends PrivateModule { 112ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 113ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com @Override 114ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com protected void configure() { 115ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com install(ThrowingProviderBinder.forModule(this)); 116ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 117ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 118ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com @CheckedProvides(RpcProvider.class) @Named("fruit") @Exposed 119ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com String provideApples() { 120ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com return "apple"; 121ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 122ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 123ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 124ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 125ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com public void testNoAnnotationNoScope() throws BindException, RemoteException { 126ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com Injector injector = Guice.createInjector(new TestModule()); 127ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com RpcProvider<String> provider = injector 128ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com .getInstance(Key.get(rpcProviderOfString)); 129ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com assertEquals("Works", provider.get()); 130ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 131ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 132ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com public void testWithScope() throws BindException, RemoteException { 133ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com TestModule testModule = new TestModule(); 134ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com Injector injector = Guice.createInjector(testModule); 135ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com RpcProvider<Integer> provider = injector 136ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com .getInstance(Key.get(rpcProviderOfInteger)); 137ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 138ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com assertEquals((Integer)100, provider.get()); 139ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com testModule.setNextIntToReturn(120); 140ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com assertEquals((Integer)100, provider.get()); 141ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com testScope.beginNewScope(); 142ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com assertEquals((Integer)120, provider.get()); 143ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 144ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 145ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com public void testWithAnnotation() throws BindException, RemoteException { 146ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com TestModule testModule = new TestModule(); 147ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com Injector injector = Guice.createInjector(testModule); 148ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com RpcProvider<Long> provider = injector 149ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com .getInstance(Key.get(rpcProviderOfLong, TestAnnotation.class)); 150ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com assertEquals((Long)0xffL, provider.get()); 151ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 152ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 153ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com public void testWithInjectedParameters() throws BindException, RemoteException { 154ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com TestModule testModule = new TestModule(); 155ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com Injector injector = Guice.createInjector(testModule); 156ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com RpcProvider<Pair<Double, String>> provider = injector 157ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com .getInstance(Key.get(rpcProviderOfPair)); 158ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com Pair<Double, String> pair = provider.get(); 159ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com assertEquals(pair.first, 4.0d); 160ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 161ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 162ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com public void testWithThrownException() { 163ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com TestModule testModule = new TestModule(); 164ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com Injector injector = Guice.createInjector(testModule); 165ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com RpcProvider<Float> provider = injector 166ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com .getInstance(Key.get(rpcProviderOfFloat)); 167ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com try { 168ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com provider.get(); 169ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com fail(); 170ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } catch (RemoteException e) { 171ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com fail(); 172ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } catch (BindException e) { 173ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com // good 174ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 175ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 176ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 177ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com public void testExposedMethod() throws BindException, RemoteException { 178ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com TestModule testModule = new TestModule(); 179ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com Injector injector = Guice.createInjector(testModule); 180ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com RpcProvider<String> provider = injector 181ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com .getInstance(Key.get(rpcProviderOfString, Names.named("fruit"))); 182ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com assertEquals("apple", provider.get()); 183ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 184ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 185ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com 186ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com private static class Pair<A, B> { 187b7a02b02d81c830d148355c90bc309bcd66fb592sberlin A first; 188b7a02b02d81c830d148355c90bc309bcd66fb592sberlin B second; 189b7a02b02d81c830d148355c90bc309bcd66fb592sberlin 190b7a02b02d81c830d148355c90bc309bcd66fb592sberlin Pair(A a, B b) { 191b7a02b02d81c830d148355c90bc309bcd66fb592sberlin this.first= a; 192b7a02b02d81c830d148355c90bc309bcd66fb592sberlin this.second = b; 193b7a02b02d81c830d148355c90bc309bcd66fb592sberlin } 194ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com } 195ba8a4cdebee559cd1b6ad4af2ef9f7f0d82d085dsberlin@gmail.com}