From fcf96a954fa766d1e5a90ad2e90af497ee3fb30a Mon Sep 17 00:00:00 2001 From: dsyer Date: Thu, 21 Aug 2008 12:11:22 +0000 Subject: [PATCH] RESOLVED - issue BATCH-789: Remove mark/reset from ItemReader Remove AbstractItemReader. All done (with remaining issues moved to BATCH-220). --- .../main/java/example/ExampleItemReader.java | 3 +- .../item/ItemOrientedStepHandlerTests.java | 4 +-- .../StatefulRetryStepFactoryBeanTests.java | 3 +- .../item/StepExecutorInterruptionTests.java | 8 ++--- .../core/step/item/StepHandlerStepTests.java | 17 +++++------ .../batch/jms/ExternalRetryInBatchTests.java | 21 ++++++++------ .../batch/retry/jms/ExternalRetryTests.java | 4 +-- .../batch/item/jms/JmsItemReader.java | 5 ++-- .../item/support/AbstractItemReader.java | 29 ------------------- .../item/support/DelegatingItemReader.java | 2 +- .../batch/item/support/ListItemReader.java | 2 +- .../batch/item/ItemProviderTests.java | 4 +-- .../support/AggregateItemReaderTests.java | 2 +- .../validator/ValidatingItemReaderTests.java | 8 +++-- .../repeat/support/ChunkedRepeatTests.java | 3 +- .../order/internal/OrderItemReader.java | 3 +- 16 files changed, 43 insertions(+), 75 deletions(-) delete mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/AbstractItemReader.java diff --git a/archetypes/simple-cli/src/main/java/example/ExampleItemReader.java b/archetypes/simple-cli/src/main/java/example/ExampleItemReader.java index eed8cab08..9e8fb06c6 100644 --- a/archetypes/simple-cli/src/main/java/example/ExampleItemReader.java +++ b/archetypes/simple-cli/src/main/java/example/ExampleItemReader.java @@ -1,12 +1,11 @@ package example; import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.support.AbstractItemReader; /** * {@link ItemReader} with hard-coded input data. */ -public class ExampleItemReader extends AbstractItemReader { +public class ExampleItemReader implements ItemReader { private String[] input = {"Hello world!", null}; diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepHandlerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepHandlerTests.java index 73cc2f89e..063383d5f 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepHandlerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepHandlerTests.java @@ -27,11 +27,11 @@ import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.StepExecution; import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.NoWorkFoundException; import org.springframework.batch.item.ParseException; import org.springframework.batch.item.UnexpectedInputException; -import org.springframework.batch.item.support.AbstractItemReader; import org.springframework.batch.item.support.PassthroughItemProcessor; import org.springframework.batch.repeat.policy.SimpleCompletionPolicy; import org.springframework.batch.repeat.support.RepeatTemplate; @@ -114,7 +114,7 @@ public class ItemOrientedStepHandlerTests { * @author Dave Syer * */ - private final class StubItemReader extends AbstractItemReader { + private final class StubItemReader implements ItemReader { private int count = 0; public String read() throws Exception, UnexpectedInputException, NoWorkFoundException, ParseException { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StatefulRetryStepFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StatefulRetryStepFactoryBeanTests.java index cf28b83dc..f2f9b21b1 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StatefulRetryStepFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StatefulRetryStepFactoryBeanTests.java @@ -45,7 +45,6 @@ import org.springframework.batch.core.step.AbstractStep; import org.springframework.batch.core.step.skip.SkipLimitExceededException; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.item.support.AbstractItemReader; import org.springframework.batch.item.support.ListItemReader; import org.springframework.batch.retry.RetryException; import org.springframework.batch.retry.policy.RetryCacheCapacityExceededException; @@ -339,7 +338,7 @@ public class StatefulRetryStepFactoryBeanTests { // set the cache limit lower than the number of unique un-recovered // errors expected factory.setCacheCapacity(2); - ItemReader provider = new AbstractItemReader() { + ItemReader provider = new ItemReader() { public String read() { String item = ""+count; provided.add(item); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepExecutorInterruptionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepExecutorInterruptionTests.java index d16fbc7f5..aee9aa87f 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepExecutorInterruptionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepExecutorInterruptionTests.java @@ -33,8 +33,8 @@ import org.springframework.batch.core.repository.dao.MapJobInstanceDao; import org.springframework.batch.core.repository.dao.MapStepExecutionDao; import org.springframework.batch.core.repository.support.SimpleJobRepository; import org.springframework.batch.core.step.StepExecutionSynchronizer; +import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.item.support.AbstractItemReader; import org.springframework.batch.repeat.policy.SimpleCompletionPolicy; import org.springframework.batch.repeat.support.RepeatTemplate; import org.springframework.batch.support.transaction.ResourcelessTransactionManager; @@ -78,7 +78,7 @@ public class StepExecutorInterruptionTests extends TestCase { RepeatTemplate template = new RepeatTemplate(); // N.B, If we don't set the completion policy it might run forever template.setCompletionPolicy(new SimpleCompletionPolicy(2)); - step.setItemHandler(new SimpleStepHandler(new AbstractItemReader() { + step.setItemHandler(new SimpleStepHandler(new ItemReader() { public Object read() throws Exception { // do something non-trivial (and not Thread.sleep()) double foo = 1; @@ -115,7 +115,7 @@ public class StepExecutorInterruptionTests extends TestCase { Thread processingThread = createThread(stepExecution); - step.setItemHandler(new SimpleStepHandler(new AbstractItemReader() { + step.setItemHandler(new SimpleStepHandler(new ItemReader() { public Object read() throws Exception { return null; } @@ -152,7 +152,7 @@ public class StepExecutorInterruptionTests extends TestCase { public void testLockNotReleasedIfChunkFails() throws Exception { - step.setItemHandler(new SimpleStepHandler(new AbstractItemReader() { + step.setItemHandler(new SimpleStepHandler(new ItemReader() { public Object read() throws Exception { throw new RuntimeException("Planned!"); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepHandlerStepTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepHandlerStepTests.java index 14b6b4f31..84ac7a402 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepHandlerStepTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepHandlerStepTests.java @@ -50,7 +50,6 @@ import org.springframework.batch.item.ItemStreamSupport; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.MarkFailedException; import org.springframework.batch.item.ResetFailedException; -import org.springframework.batch.item.support.AbstractItemReader; import org.springframework.batch.item.support.ListItemReader; import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.policy.DefaultResultCompletionPolicy; @@ -192,7 +191,7 @@ public class StepHandlerStepTests extends TestCase { public void testIncrementRollbackCount() { - ItemReader itemReader = new AbstractItemReader() { + ItemReader itemReader = new ItemReader() { public String read() throws Exception { throw new RuntimeException(); @@ -215,7 +214,7 @@ public class StepHandlerStepTests extends TestCase { public void testExitCodeDefaultClassification() throws Exception { - ItemReader itemReader = new AbstractItemReader() { + ItemReader itemReader = new ItemReader() { public String read() throws Exception { throw new RuntimeException(); @@ -239,7 +238,7 @@ public class StepHandlerStepTests extends TestCase { public void testExitCodeCustomClassification() throws Exception { - ItemReader itemReader = new AbstractItemReader() { + ItemReader itemReader = new ItemReader() { public String read() throws Exception { throw new RuntimeException(); @@ -352,7 +351,7 @@ public class StepHandlerStepTests extends TestCase { * Restartable. */ public void testRestartJobOnNonRestartableTasklet() throws Exception { - step.setItemHandler(new SimpleStepHandler(new AbstractItemReader() { + step.setItemHandler(new SimpleStepHandler(new ItemReader() { public String read() throws Exception { return "foo"; } @@ -520,7 +519,7 @@ public class StepHandlerStepTests extends TestCase { step.setInterruptionPolicy(interruptionPolicy); - ItemReader itemReader = new AbstractItemReader() { + ItemReader itemReader = new ItemReader() { public String read() throws Exception { throw new RuntimeException(); @@ -550,7 +549,7 @@ public class StepHandlerStepTests extends TestCase { public void testStatusForNormalFailure() throws Exception { - ItemReader itemReader = new AbstractItemReader() { + ItemReader itemReader = new ItemReader() { public String read() throws Exception { // Trigger a rollback throw new RuntimeException("Foo"); @@ -577,7 +576,7 @@ public class StepHandlerStepTests extends TestCase { public void testStatusForErrorFailure() throws Exception { - ItemReader itemReader = new AbstractItemReader() { + ItemReader itemReader = new ItemReader() { public String read() throws Exception { // Trigger a rollback throw new Error("Foo"); @@ -604,7 +603,7 @@ public class StepHandlerStepTests extends TestCase { public void testStatusForResetFailedException() throws Exception { - ItemReader itemReader = new AbstractItemReader() { + ItemReader itemReader = new ItemReader() { public String read() throws Exception { // Trigger a rollback throw new RuntimeException("Foo"); diff --git a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/jms/ExternalRetryInBatchTests.java b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/jms/ExternalRetryInBatchTests.java index 0aed1db90..4f3428397 100644 --- a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/jms/ExternalRetryInBatchTests.java +++ b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/jms/ExternalRetryInBatchTests.java @@ -16,23 +16,24 @@ package org.springframework.batch.jms; -import static org.junit.Assert.*; -import org.junit.Before; -import org.junit.After; -import org.junit.Test; -import org.junit.runner.RunWith; +import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.List; import javax.sql.DataSource; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemRecoverer; -import org.springframework.batch.item.support.AbstractItemReader; import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.RepeatCallback; import org.springframework.batch.repeat.RepeatContext; import org.springframework.batch.repeat.policy.SimpleCompletionPolicy; +import org.springframework.batch.repeat.support.RepeatSynchronizationManager; import org.springframework.batch.repeat.support.RepeatTemplate; import org.springframework.batch.retry.RecoveryCallback; import org.springframework.batch.retry.RetryCallback; @@ -41,15 +42,15 @@ import org.springframework.batch.retry.callback.RecoveryRetryCallback; import org.springframework.batch.retry.policy.RecoveryCallbackRetryPolicy; import org.springframework.batch.retry.policy.SimpleRetryPolicy; import org.springframework.batch.retry.support.RetryTemplate; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.jms.core.JmsTemplate; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; -import org.springframework.beans.factory.annotation.Autowired; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "/org/springframework/batch/jms/jms-context.xml") @@ -151,6 +152,8 @@ public class ExternalRetryInBatchTests { callback.setRecoveryCallback(new RecoveryCallback() { public Object recover(RetryContext context) { + // aggressive commit on a recovery + RepeatSynchronizationManager.setCompleteOnly(); return provider.recover(item, context.getLastThrowable()); } }); @@ -210,7 +213,7 @@ public class ExternalRetryInBatchTests { return msgs; } - private abstract class ItemReaderRecoverer extends AbstractItemReader implements ItemRecoverer { + private interface ItemReaderRecoverer extends ItemReader, ItemRecoverer { } } diff --git a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java index 095bd45d8..e3ad25783 100644 --- a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java +++ b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java @@ -28,9 +28,9 @@ import javax.sql.DataSource; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemRecoverer; import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.item.support.AbstractItemReader; import org.springframework.batch.retry.RecoveryCallback; import org.springframework.batch.retry.RetryCallback; import org.springframework.batch.retry.RetryContext; @@ -259,7 +259,7 @@ public class ExternalRetryTests { return msgs; } - private abstract class ItemReaderRecoverer extends AbstractItemReader implements ItemRecoverer { + private interface ItemReaderRecoverer extends ItemReader, ItemRecoverer { } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsItemReader.java index 06fd294a3..e7f8540b9 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/jms/JmsItemReader.java @@ -22,12 +22,11 @@ import javax.jms.Message; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.batch.item.NewItemIdentifier; import org.springframework.batch.item.ItemKeyGenerator; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemRecoverer; +import org.springframework.batch.item.NewItemIdentifier; import org.springframework.batch.item.UnexpectedInputException; -import org.springframework.batch.item.support.AbstractItemReader; import org.springframework.jms.JmsException; import org.springframework.jms.core.JmsOperations; import org.springframework.jms.core.JmsTemplate; @@ -45,7 +44,7 @@ import org.springframework.util.Assert; * @author Dave Syer * */ -public class JmsItemReader extends AbstractItemReader implements ItemRecoverer, ItemKeyGenerator, +public class JmsItemReader implements ItemReader, ItemRecoverer, ItemKeyGenerator, NewItemIdentifier { protected Log logger = LogFactory.getLog(getClass()); diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/AbstractItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/AbstractItemReader.java deleted file mode 100644 index ca86d4ad7..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/AbstractItemReader.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2006-2007 the original author or 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 org.springframework.batch.item.support; - -import org.springframework.batch.item.ItemReader; - - -/** - * Base class for {@link ItemReader} implementations. - * @author Dave Syer - * - */ -public abstract class AbstractItemReader implements ItemReader { - -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/DelegatingItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/DelegatingItemReader.java index 3da1d3983..bbdd3a7fa 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/DelegatingItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/DelegatingItemReader.java @@ -29,7 +29,7 @@ import org.springframework.util.Assert; * * @author Dave Syer */ -public class DelegatingItemReader extends AbstractItemReader implements InitializingBean { +public class DelegatingItemReader implements ItemReader, InitializingBean { private ItemReader itemReader; diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/ListItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/ListItemReader.java index 4794dad4e..50361271b 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/ListItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/ListItemReader.java @@ -28,7 +28,7 @@ import org.springframework.batch.item.ItemReader; * @author Dave Syer * */ -public class ListItemReader extends AbstractItemReader { +public class ListItemReader implements ItemReader { private List list; diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/ItemProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/ItemProviderTests.java index 31cc351eb..57d089ef7 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/ItemProviderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/ItemProviderTests.java @@ -16,14 +16,12 @@ package org.springframework.batch.item; -import org.springframework.batch.item.support.AbstractItemReader; - import junit.framework.TestCase; public class ItemProviderTests extends TestCase { - ItemReader provider = new AbstractItemReader() { + ItemReader provider = new ItemReader() { public String read() { return "foo"; } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/AggregateItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/AggregateItemReaderTests.java index 8d0cace50..35996366b 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/AggregateItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/AggregateItemReaderTests.java @@ -19,7 +19,7 @@ public class AggregateItemReaderTests { @Before public void setUp() { // create mock for input - input = new AbstractItemReader>() { + input = new ItemReader>() { private int count = 0; diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemReaderTests.java index 63363c05f..80ded6c01 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemReaderTests.java @@ -15,11 +15,13 @@ */ package org.springframework.batch.item.validator; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; import junit.framework.TestCase; -import static org.easymock.EasyMock.*; import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.support.AbstractItemReader; /** * @author Lucas Ward @@ -98,7 +100,7 @@ public class ValidatingItemReaderTests extends TestCase { verify(validator); } - private static class MockItemReader extends AbstractItemReader { + private static class MockItemReader implements ItemReader { Object value; diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/ChunkedRepeatTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/ChunkedRepeatTests.java index 288c67eb1..0a4da508a 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/ChunkedRepeatTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/ChunkedRepeatTests.java @@ -17,7 +17,6 @@ package org.springframework.batch.repeat.support; import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.support.AbstractItemReader; import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.RepeatCallback; import org.springframework.batch.repeat.RepeatContext; @@ -147,7 +146,7 @@ public class ChunkedRepeatTests extends AbstractTradeBatchTests { while (!chunker.ready()) { - ItemReader truncated = new AbstractItemReader() { + ItemReader truncated = new ItemReader() { int count = 0; public Trade read() throws Exception { diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/order/internal/OrderItemReader.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/order/internal/OrderItemReader.java index 3a150d061..d24a79d56 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/order/internal/OrderItemReader.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/order/internal/OrderItemReader.java @@ -23,7 +23,6 @@ import org.apache.commons.logging.LogFactory; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.file.mapping.FieldSet; import org.springframework.batch.item.file.mapping.FieldSetMapper; -import org.springframework.batch.item.support.AbstractItemReader; import org.springframework.batch.sample.domain.order.Address; import org.springframework.batch.sample.domain.order.BillingInfo; import org.springframework.batch.sample.domain.order.Customer; @@ -35,7 +34,7 @@ import org.springframework.batch.sample.domain.order.ShippingInfo; * @author peter.zozom * */ -public class OrderItemReader extends AbstractItemReader { +public class OrderItemReader implements ItemReader { private static Log log = LogFactory.getLog(OrderItemReader.class); private Order order;