JAMES-2138 move MailAddress to a new james-core project

        move james.core package to james.server.core to avoid conflict


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/936746b9
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/936746b9
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/936746b9

Branch: refs/heads/master
Commit: 936746b9a8c85fbe2c303baedfdb7a067813f633
Parents: e9cb6e9
Author: Matthieu Baechler <matth...@apache.org>
Authored: Mon Sep 4 17:03:41 2017 +0200
Committer: benwa <btell...@linagora.com>
Committed: Sat Sep 9 10:46:01 2017 +0700

----------------------------------------------------------------------
 core/pom.xml                                    |  65 ++
 .../java/org/apache/james/core/MailAddress.java | 623 ++++++++++++++++
 .../org/apache/james/core/MailAddressTest.java  | 229 ++++++
 .../james/ai/classic/BayesianAnalysis.java      |   2 +-
 mailet/api/pom.xml                              |   4 +
 .../src/main/java/org/apache/mailet/Mail.java   |   1 +
 .../java/org/apache/mailet/MailAddress.java     | 550 +--------------
 .../java/org/apache/mailet/MailetContext.java   |   1 +
 .../main/java/org/apache/mailet/Matcher.java    |   2 +
 .../org/apache/mailet/PerRecipientHeaders.java  |   2 +
 .../java/org/apache/mailet/MailAddressTest.java | 229 ------
 .../base/AutomaticallySentMailDetectorImpl.java |   2 +-
 .../org/apache/mailet/base/GenericMatcher.java  |   2 +-
 .../mailet/base/GenericRecipientMatcher.java    |   2 +-
 .../org/apache/mailet/base/MatcherInverter.java |   2 +-
 .../AutomaticallySentMailDetectorImplTest.java  |   2 +-
 .../apache/mailet/base/MailAddressFixture.java  |   2 +-
 .../apache/mailet/base/MatcherInverterTest.java |   2 +-
 .../org/apache/mailet/base/test/FakeMail.java   |   2 +-
 .../mailet/base/test/FakeMailContext.java       |   2 +-
 .../org/apache/mailet/base/test/MailUtil.java   |   2 +-
 .../james/transport/mailets/AbstractSign.java   |   2 +-
 .../transport/matcher/IsSMIMEEncrypted.java     |   2 +-
 .../james/transport/matcher/IsSMIMESigned.java  |   2 +-
 .../matcher/IsX509CertificateSubject.java       |   2 +-
 .../transport/mailets/ICALToJsonAttribute.java  |   2 +-
 .../james/transport/mailets/model/ICAL.java     |   2 +-
 .../mailets/ICALToJsonAttributeTest.java        |   2 +-
 .../james/transport/mailets/model/ICALTest.java |   2 +-
 .../transport/mailets/AddDeliveredToHeader.java |   2 +-
 .../james/transport/mailets/ClamAVScan.java     |   2 +-
 .../transport/mailets/PostmasterAlias.java      |   2 +-
 .../transport/mailets/RecipientToLowerCase.java |   2 +-
 .../transport/mailets/UseHeaderRecipients.java  |   2 +-
 .../matchers/AbstractQuotaMatcher.java          |   2 +-
 .../apache/james/transport/matchers/All.java    |   2 +-
 .../matchers/AttachmentFileNameIs.java          |   2 +-
 .../transport/matchers/CommandForListserv.java  |   2 +-
 .../matchers/CommandListservMatcher.java        |   2 +-
 .../matchers/CompareNumericHeaderValue.java     |   2 +-
 .../james/transport/matchers/FetchedFrom.java   |   2 +-
 .../transport/matchers/GenericRegexMatcher.java |   2 +-
 .../james/transport/matchers/HasAttachment.java |   2 +-
 .../matchers/HasHabeasWarrantMark.java          |   2 +-
 .../james/transport/matchers/HasHeader.java     |   2 +-
 .../transport/matchers/HasHeaderWithPrefix.java |   2 +-
 .../transport/matchers/HasMailAttribute.java    |   2 +-
 .../matchers/HasMailAttributeWithValue.java     |   2 +-
 .../HasMailAttributeWithValueRegex.java         |   2 +-
 .../apache/james/transport/matchers/HostIs.java |   2 +-
 .../james/transport/matchers/HostIsLocal.java   |   2 +-
 .../transport/matchers/IsSingleRecipient.java   |   2 +-
 .../james/transport/matchers/RecipientIs.java   |   2 +-
 .../transport/matchers/RecipientIsLocal.java    |   2 +-
 .../transport/matchers/RecipientIsRegex.java    |   2 +-
 .../james/transport/matchers/RelayLimit.java    |   2 +-
 .../transport/matchers/SMTPAuthSuccessful.java  |   2 +-
 .../transport/matchers/SMTPAuthUserIs.java      |   2 +-
 .../transport/matchers/SMTPIsAuthNetwork.java   |   2 +-
 .../james/transport/matchers/SenderHostIs.java  |   2 +-
 .../transport/matchers/SenderHostIsLocal.java   |   2 +-
 .../james/transport/matchers/SenderIs.java      |   2 +-
 .../james/transport/matchers/SenderIsLocal.java |   2 +-
 .../james/transport/matchers/SenderIsNull.java  |   2 +-
 .../james/transport/matchers/SenderIsRegex.java |   2 +-
 .../james/transport/matchers/SentByMailet.java  |   2 +-
 .../transport/matchers/SizeGreaterThan.java     |   2 +-
 .../james/transport/matchers/SubjectIs.java     |   2 +-
 .../transport/matchers/SubjectStartsWith.java   |   2 +-
 .../james/transport/matchers/TooManyLines.java  |   2 +-
 .../transport/matchers/TooManyRecipients.java   |   2 +-
 .../apache/james/transport/matchers/UserIs.java |   2 +-
 .../utils/MailAddressCollectionReader.java      |   2 +-
 .../james/transport/mailets/LogMessageTest.java |   2 +-
 .../mailets/RecipientToLowerCaseTest.java       |   2 +-
 .../transport/mailets/ToProcessorTest.java      |   2 +-
 .../mailets/UseHeaderRecipientsTest.java        |   2 +-
 .../matchers/AbstractHasMailAttributeTest.java  |   2 +-
 .../HasMailAttributeWithValueRegexTest.java     |   2 +-
 .../matchers/HasMailAttributeWithValueTest.java |   2 +-
 .../matchers/RecipientIsLocalTest.java          |   2 +-
 .../matchers/SMTPAuthSuccessfulTest.java        |   2 +-
 .../transport/matchers/SMTPAuthUserIsTest.java  |   3 +-
 .../matchers/SMTPIsAuthNetworkTest.java         |   2 +-
 .../matchers/SenderHostIsLocalTest.java         |   2 +-
 .../transport/matchers/SenderHostIsTest.java    |   2 +-
 .../transport/matchers/SenderIsLocalTest.java   |   2 +-
 .../transport/matchers/SenderIsNullTest.java    |   2 +-
 .../transport/matchers/SenderIsRegexTest.java   |   2 +-
 .../james/transport/matchers/SenderIsTest.java  |   2 +-
 .../transport/matchers/SentByMailetTest.java    |   2 +-
 .../james/transport/matchers/SubjectIsTest.java |   2 +-
 .../matchers/SubjectStartsWithTest.java         |   2 +-
 .../transport/matchers/TooManyLinesTest.java    |   2 +-
 .../matchers/TooManyRecipientsTest.java         |   2 +-
 .../util/MailAddressCollectionReaderTest.java   |   2 +-
 pom.xml                                         |   6 +
 .../lmtp/core/DataLineMessageHookHandler.java   |   2 +-
 .../lmtp/hook/DeliverToRecipientHook.java       |   2 +-
 .../protocols/lmtp/AbstractLMTPServerTest.java  |   2 +-
 protocols/pom.xml                               |   5 +
 protocols/smtp/pom.xml                          |   5 +-
 .../james/protocols/smtp/MailAddress.java       | 469 +-----------
 .../protocols/smtp/MailAddressException.java    |  12 +-
 .../james/protocols/smtp/MailEnvelope.java      |   2 +
 .../james/protocols/smtp/MailEnvelopeImpl.java  |   2 +
 .../james/protocols/smtp/SMTPSessionImpl.java   |   1 +
 .../AbstractAuthRequiredToRelayRcptHook.java    |   2 +-
 ...tSenderAuthIdentifyVerificationRcptHook.java |   2 +-
 .../AcceptRecipientIfRelayingIsAllowed.java     |   2 +-
 .../protocols/smtp/core/DataCmdHandler.java     |   3 +-
 .../protocols/smtp/core/MailCmdHandler.java     |   2 +-
 .../smtp/core/PostmasterAbuseRcptHook.java      |   2 +-
 .../protocols/smtp/core/RcptCmdHandler.java     |   2 +-
 .../smtp/core/ReceivedDataLineFilter.java       |   2 +-
 .../core/fastfail/AbstractGreylistHandler.java  |   2 +-
 .../core/fastfail/AbstractValidRcptHandler.java |   6 +-
 .../smtp/core/fastfail/DNSRBLHandler.java       |   2 +-
 .../smtp/core/fastfail/MaxRcptHandler.java      |   2 +-
 .../fastfail/ResolvableEhloHeloHandler.java     |   3 +-
 .../smtp/core/fastfail/SpamTrapHandler.java     |   2 +-
 .../fastfail/SupressDuplicateRcptHandler.java   |   6 +-
 .../core/fastfail/ValidSenderDomainHandler.java |   2 +-
 .../james/protocols/smtp/hook/MailHook.java     |   6 +-
 .../james/protocols/smtp/hook/RcptHook.java     |   2 +-
 .../james/protocols/smtp/hook/SimpleHook.java   |  26 +-
 .../protocols/smtp/AbstractSMTPServerTest.java  |   1 +
 .../smtp/core/fastfail/DNSRBLHandlerTest.java   |  15 +-
 .../smtp/core/fastfail/MaxRcptHandlerTest.java  |   7 +-
 .../core/fastfail/MaxUnknownCmdHandlerTest.java |   3 +-
 .../fastfail/ResolvableEhloHeloHandlerTest.java |  11 +-
 .../smtp/core/fastfail/SpamTrapHandlerTest.java |   6 +-
 .../fastfail/ValidSenderDomainHandlerTest.java  |   5 +-
 .../james/core/InternetHeadersInputStream.java  |  93 ---
 .../james/core/JamesServerResourceLoader.java   |  72 --
 .../java/org/apache/james/core/MailHeaders.java | 187 -----
 .../java/org/apache/james/core/MailImpl.java    | 691 ------------------
 .../james/core/MimeMessageCopyOnWriteProxy.java | 561 ---------------
 .../james/core/MimeMessageInputStream.java      | 127 ----
 .../core/MimeMessageInputStreamSource.java      | 174 -----
 .../apache/james/core/MimeMessageSource.java    |  84 ---
 .../org/apache/james/core/MimeMessageUtil.java  | 311 --------
 .../apache/james/core/MimeMessageWrapper.java   | 705 -------------------
 .../core/filesystem/ClassPathResource.java      | 110 ---
 .../james/core/filesystem/FileSystemImpl.java   |  60 --
 .../core/filesystem/FileSystemResource.java     |  44 --
 .../apache/james/core/filesystem/Resource.java  |  29 -
 .../james/core/filesystem/ResourceFactory.java  | 100 ---
 .../james/core/filesystem/ResourceUtils.java    |  41 --
 .../apache/james/core/filesystem/SimpleUrl.java |  74 --
 .../james/core/filesystem/UrlResource.java      |  59 --
 .../java/org/apache/james/core/package.html     |  21 -
 .../server/core/InternetHeadersInputStream.java |  93 +++
 .../server/core/JamesServerResourceLoader.java  |  72 ++
 .../apache/james/server/core/MailHeaders.java   | 187 +++++
 .../org/apache/james/server/core/MailImpl.java  | 691 ++++++++++++++++++
 .../core/MimeMessageCopyOnWriteProxy.java       | 561 +++++++++++++++
 .../server/core/MimeMessageInputStream.java     | 127 ++++
 .../core/MimeMessageInputStreamSource.java      | 174 +++++
 .../james/server/core/MimeMessageSource.java    |  84 +++
 .../james/server/core/MimeMessageUtil.java      | 311 ++++++++
 .../james/server/core/MimeMessageWrapper.java   | 705 +++++++++++++++++++
 .../core/filesystem/ClassPathResource.java      | 110 +++
 .../server/core/filesystem/FileSystemImpl.java  |  60 ++
 .../core/filesystem/FileSystemResource.java     |  44 ++
 .../james/server/core/filesystem/Resource.java  |  29 +
 .../server/core/filesystem/ResourceFactory.java | 100 +++
 .../server/core/filesystem/ResourceUtils.java   |  41 ++
 .../james/server/core/filesystem/SimpleUrl.java |  74 ++
 .../server/core/filesystem/UrlResource.java     |  59 ++
 .../org/apache/james/server/core/package.html   |  21 +
 .../org/apache/james/core/MailHeadersTest.java  |  43 --
 .../org/apache/james/core/MailImplTest.java     | 115 ---
 .../james/core/MailTestAllImplementations.java  |  72 --
 .../core/MimeMessageCopyOnWriteProxyTest.java   | 279 --------
 .../core/MimeMessageFromMimeMessageTest.java    |  31 -
 .../core/MimeMessageFromSharedStreamTest.java   |  36 -
 .../james/core/MimeMessageFromStreamTest.java   |  59 --
 .../core/MimeMessageInputStreamSourceTest.java  |  60 --
 .../org/apache/james/core/MimeMessageTest.java  | 437 ------------
 .../apache/james/core/MimeMessageUtilTest.java  |  65 --
 .../james/core/MimeMessageWrapperTest.java      | 289 --------
 .../core/filesystem/FileSystemImplTest.java     |  32 -
 .../james/core/filesystem/SimpleUrlTest.java    | 114 ---
 .../james/server/core/MailHeadersTest.java      |  43 ++
 .../apache/james/server/core/MailImplTest.java  | 115 +++
 .../server/core/MailTestAllImplementations.java |  72 ++
 .../core/MimeMessageCopyOnWriteProxyTest.java   | 279 ++++++++
 .../core/MimeMessageFromMimeMessageTest.java    |  31 +
 .../core/MimeMessageFromSharedStreamTest.java   |  36 +
 .../server/core/MimeMessageFromStreamTest.java  |  59 ++
 .../core/MimeMessageInputStreamSourceTest.java  |  60 ++
 .../james/server/core/MimeMessageTest.java      | 437 ++++++++++++
 .../james/server/core/MimeMessageUtilTest.java  |  65 ++
 .../server/core/MimeMessageWrapperTest.java     | 289 ++++++++
 .../core/filesystem/FileSystemImplTest.java     |  32 +
 .../server/core/filesystem/SimpleUrlTest.java   | 114 +++
 .../com/custom/matchers/AnotherMatcher.java     |   2 +-
 .../james/transport/matchers/CustomMatcher.java |   2 +-
 .../james/modules/CommonServicesModule.java     |   4 +-
 .../james/modules/TestFilesystemModule.java     |   2 +-
 .../utils/FileConfigurationProviderTest.java    |   4 +-
 .../utils/InMemoryMailRepositoryStoreTest.java  |   4 +-
 .../modules/server/MemoryMailQueueFactory.java  |   2 +-
 .../context/JamesServerApplicationContext.java  |   2 +-
 .../container/spring/tool/James23Importer.java  |   2 +-
 .../spring/filesystem/FileSystemImplTest.java   |   2 +-
 .../apache/james/user/api/UsersRepository.java  |   2 +-
 .../apache/james/user/api/model/JamesUser.java  |   2 +-
 .../mailrepository/file/FileMailRepository.java |   4 +-
 .../mailrepository/file/MBoxMailRepository.java |   2 +-
 .../file/MimeMessageStreamRepositorySource.java |   4 +-
 .../mailrepository/jcr/JCRMailRepository.java   |   4 +-
 .../mailrepository/jdbc/JDBCMailRepository.java |   8 +-
 .../mailrepository/jdbc/MessageInputStream.java |   6 +-
 .../jdbc/MimeMessageJDBCSource.java             |   6 +-
 .../user/jdbc/JamesUsersJdbcRepository.java     |   2 +-
 .../james/jmap/api/vacation/RecipientId.java    |   2 +-
 .../AbstractNotificationRegistryTest.java       |   2 +-
 .../ldap/ReadOnlyUsersLDAPRepositoryTest.java   |   2 +-
 .../user/ldap/ReadOnlyUsersLDAPRepository.java  |   2 +-
 .../rrt/lib/AbstractRecipientRewriteTable.java  |   2 +-
 .../rrt/lib/RecipientRewriteTableUtil.java      |   2 +-
 .../james/user/lib/AbstractUsersRepository.java |   2 +-
 .../james/user/lib/model/DefaultJamesUser.java  |   4 +-
 .../AbstractMailRepositoryTest.java             |   8 +-
 .../user/lib/AbstractUsersRepositoryTest.java   |   2 +-
 .../mailets/TemporaryFilesystemModule.java      |   2 +-
 .../mailets/AmqpForwardAttachmentTest.java      |   2 +-
 .../mailets/ICSAttachmentWorkflowTest.java      |   2 +-
 .../transport/mailets/StripAttachmentTest.java  |   2 +-
 .../api/mock/ExceptionThrowingMatcher.java      |   2 +-
 .../api/mock/MockMailetContext.java             |   2 +-
 .../mailetcontainer/api/mock/MockMatcher.java   |   2 +-
 .../impl/JamesMailetContext.java                |   4 +-
 .../mailetcontainer/impl/ProcessorUtil.java     |   2 +-
 .../impl/camel/MatcherSplitter.java             |   4 +-
 .../jmx/JMXStateMailetProcessorListener.java    |   2 +-
 .../mailetcontainer/impl/matchers/And.java      |   2 +-
 .../mailetcontainer/impl/matchers/Not.java      |   2 +-
 .../james/mailetcontainer/impl/matchers/Or.java |   2 +-
 .../mailetcontainer/impl/matchers/Xor.java      |   2 +-
 .../lib/AbstractStateMailetProcessor.java       |   2 +-
 .../impl/JamesMailetContextTest.java            |   2 +-
 .../mailetcontainer/impl/matchers/AndTest.java  |   2 +-
 .../mailetcontainer/impl/matchers/NotTest.java  |   2 +-
 .../mailetcontainer/impl/matchers/OrTest.java   |   2 +-
 .../mailetcontainer/impl/matchers/XorTest.java  |   2 +-
 .../AbstractStateCompositeProcessorTest.java    |   2 +-
 .../lib/AbstractStateMailetProcessorTest.java   |   4 +-
 .../mailets/AbstractRecipientRewriteTable.java  |   4 +-
 .../transport/mailets/BayesianAnalysis.java     |   2 +-
 .../apache/james/transport/mailets/Bounce.java  |   2 +-
 .../james/transport/mailets/DSNBounce.java      |   4 +-
 .../apache/james/transport/mailets/Forward.java |   2 +-
 .../james/transport/mailets/JDBCAlias.java      |   2 +-
 .../mailets/JDBCRecipientRewriteTable.java      |   2 +-
 .../transport/mailets/NotifyPostmaster.java     |   2 +-
 .../james/transport/mailets/NotifySender.java   |   2 +-
 .../mailets/RecipientRewriteTableProcessor.java |   2 +-
 .../james/transport/mailets/Redirect.java       |   2 +-
 .../james/transport/mailets/RemoteDelivery.java |   2 +-
 .../apache/james/transport/mailets/Resend.java  |   2 +-
 .../org/apache/james/transport/mailets/SPF.java |   2 +-
 .../apache/james/transport/mailets/Sieve.java   |   2 +-
 .../james/transport/mailets/ToSenderFolder.java |   2 +-
 .../transport/mailets/WhiteListManager.java     |   2 +-
 .../mailets/XMLRecipientRewriteTable.java       |   2 +-
 .../mailets/delivery/DeliveryUtils.java         |   2 +-
 .../mailets/delivery/MailDispatcher.java        |   2 +-
 .../transport/mailets/delivery/MailStore.java   |   2 +-
 .../mailets/delivery/MailboxAppender.java       |   2 +-
 .../mailets/delivery/SimpleMailStore.java       |   2 +-
 .../transport/mailets/jsieve/ActionContext.java |   2 +-
 .../transport/mailets/jsieve/ActionUtils.java   |   2 +-
 .../mailets/jsieve/FileIntoAction.java          |   2 +-
 .../mailets/jsieve/RedirectAction.java          |   2 +-
 .../transport/mailets/jsieve/RejectAction.java  |   2 +-
 .../mailets/jsieve/ResourceLocator.java         |   2 +-
 .../mailets/jsieve/SieveMailAdapter.java        |   2 +-
 .../mailets/jsieve/VacationAction.java          |   2 +-
 .../transport/mailets/jsieve/VacationReply.java |   2 +-
 .../mailets/jsieve/delivery/SieveExecutor.java  |   2 +-
 .../mailets/jsieve/delivery/SievePoster.java    |   2 +-
 .../mailets/redirect/AddressExtractor.java      |   2 +-
 .../redirect/MailMessageAlteringUtils.java      |   2 +-
 .../mailets/redirect/MailModifier.java          |   4 +-
 .../mailets/redirect/NotifyMailetsMessage.java  |   2 +-
 .../mailets/redirect/ProcessRedirectNotify.java |   2 +-
 .../mailets/redirect/RedirectNotify.java        |   2 +-
 .../mailets/redirect/SpecialAddress.java        |   2 +-
 ...ddressesArrayToMailAddressListConverter.java |   2 +-
 .../mailets/remoteDelivery/Bouncer.java         |   2 +-
 .../InternetAddressConverter.java               |   2 +-
 .../mailets/remoteDelivery/MailDelivrer.java    |   2 +-
 .../matchers/AbstractSQLWhitelistMatcher.java   |   2 +-
 .../matchers/AbstractStorageQuota.java          |   2 +-
 .../transport/matchers/InSpammerBlacklist.java  |   2 +-
 .../james/transport/matchers/IsInWhiteList.java |   2 +-
 .../james/transport/matchers/IsOverQuota.java   |   2 +-
 .../transport/matchers/MailboxQuotaFixed.java   |   2 +-
 .../matchers/NetworkIsInWhitelist.java          |   2 +-
 .../transport/matchers/RemoteAddrInNetwork.java |   2 +-
 .../matchers/RemoteAddrNotInNetwork.java        |   2 +-
 .../transport/matchers/SenderInFakeDomain.java  |   2 +-
 .../james/transport/util/MailAddressUtils.java  |   2 +-
 .../james/transport/util/RecipientsUtils.java   |   2 +-
 .../james/transport/util/ReplyToUtils.java      |   2 +-
 .../james/transport/util/SenderUtils.java       |   2 +-
 .../transport/util/SpecialAddressesUtils.java   |   2 +-
 .../apache/james/transport/util/TosUtils.java   |   2 +-
 .../samples/mailets/InstrumentationMailet.java  |   2 +-
 .../james/transport/mailets/BounceTest.java     |   2 +-
 .../james/transport/mailets/DSNBounceTest.java  |   2 +-
 .../james/transport/mailets/ForwardTest.java    |   2 +-
 .../transport/mailets/NotifyPostmasterTest.java |   2 +-
 .../transport/mailets/NotifySenderTest.java     |   2 +-
 .../RecipientRewriteTableProcessorTest.java     |   2 +-
 .../transport/mailets/RecordingMailContext.java |   2 +-
 .../james/transport/mailets/RedirectTest.java   |   2 +-
 .../james/transport/mailets/ResendTest.java     |   2 +-
 .../transport/mailets/ResourceLocatorTest.java  |   2 +-
 .../mailets/delivery/LocalDeliveryTest.java     |   2 +-
 .../mailets/delivery/MailDispatcherTest.java    |   2 +-
 .../mailets/delivery/SieveIntegrationTest.java  |   2 +-
 .../mailets/delivery/SimpleMailStoreTest.java   |   2 +-
 .../mailets/delivery/ToRecipientFolderTest.java |   2 +-
 .../managesieve/ManageSieveMailetTestCase.java  |   2 +-
 .../mailets/redirect/AddressExtractorTest.java  |   2 +-
 .../mailets/redirect/MailModifierTest.java      |   2 +-
 .../redirect/NotifyMailetsMessageTest.java      |   2 +-
 .../mailets/redirect/SpecialAddressTest.java    |   2 +-
 .../InternetAddressConverterTest.java           |   2 +-
 .../matchers/InSpammerBlacklistTest.java        |   2 +-
 .../transport/matchers/IsOverQuotaTest.java     |   2 +-
 .../matchers/RemoteAddrInNetworkTest.java       |   2 +-
 .../matchers/RemoteAddrNotInNetworkTest.java    |   2 +-
 .../transport/util/MailAddressUtilsTest.java    |   2 +-
 .../transport/util/RecipientsUtilsTest.java     |   2 +-
 .../james/transport/util/ReplyToUtilsTest.java  |   2 +-
 .../james/transport/util/SenderUtilsTest.java   |   2 +-
 .../util/SpecialAddressesUtilsTest.java         |   2 +-
 .../james/transport/util/TosUtilsTest.java      |   2 +-
 .../org/apache/james/fetchmail/Account.java     |   2 +-
 .../james/fetchmail/MessageProcessor.java       |   4 +-
 .../james/fetchmail/ParsedConfiguration.java    |   2 +-
 .../james/fetchmail/ProcessorAbstract.java      |   2 +-
 .../james/jmap/UserProvisioningFilter.java      |   2 +-
 .../apache/james/jmap/mailet/SentByJmap.java    |   2 +-
 .../james/jmap/mailet/VacationMailet.java       |   2 +-
 .../apache/james/jmap/mailet/VacationReply.java |   2 +-
 .../org/apache/james/jmap/send/MailFactory.java |   4 +-
 .../james/jmap/mailet/SentByJmapTest.java       |   2 +-
 .../james/jmap/mailet/VacationMailetTest.java   |   2 +-
 .../james/jmap/mailet/VacationReplyTest.java    |   2 +-
 .../apache/james/jmap/send/MailFactoryTest.java |   2 +-
 .../james/lmtpserver/DataLineLMTPHandler.java   |   9 +-
 .../hook/MailboxDeliverToRecipientHandler.java  |   2 +-
 .../AddDefaultAttributesMessageHook.java        |   2 +-
 .../DataLineJamesMessageHookHandler.java        |  25 +-
 .../james/smtpserver/JamesDataCmdHandler.java   |   4 +-
 .../james/smtpserver/MailPriorityHandler.java   |   2 +-
 .../james/smtpserver/SendMailHandler.java       |   2 +-
 .../SenderAuthIdentifyVerificationRcptHook.java |   2 +-
 .../fastfail/JDBCGreylistHandler.java           |   2 +-
 .../james/smtpserver/fastfail/SPFHandler.java   |   2 +-
 .../smtpserver/fastfail/ValidRcptHandler.java   |   2 +-
 .../james/smtpserver/fastfail/ValidRcptMX.java  |   2 +-
 .../model/MailetMailAddressAdapter.java         |   4 +-
 .../model/ProtocolMailAddressAdapter.java       |  10 +-
 .../apache/james/smtpserver/SMTPServerTest.java |   2 +-
 .../apache/james/smtpserver/SPFHandlerTest.java |   2 +-
 .../java/org/apache/james/smtpserver/Util.java  |   2 +-
 .../james/smtpserver/ValidRcptHandlerTest.java  |   2 +-
 .../james/smtpserver/ValidRcptMXTest.java       |   7 +-
 .../james/smtpserver/mock/mailet/MockMail.java  |   2 +-
 .../smtpserver/mock/mailet/MockMailContext.java |   2 +-
 .../WebAdminServerIntegrationTest.java          |   2 +
 server/protocols/webadmin/webadmin-data/pom.xml |   4 +
 .../james/queue/activemq/ActiveMQMailQueue.java |   6 +-
 .../activemq/MimeMessageBlobMessageSource.java  |   6 +-
 .../james/queue/api/mock/MockMailQueue.java     |   2 +-
 .../apache/james/queue/file/FileMailQueue.java  |   4 +-
 .../apache/james/queue/jms/JMSMailQueue.java    |   6 +-
 .../jms/MimeMessageObjectMessageSource.java     |   2 +-
 .../queue/library/MailQueueManagement.java      |   2 +-
 .../queue/jms/AbstractJMSMailQueueTest.java     |  21 +-
 387 files changed, 6541 insertions(+), 6832 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
new file mode 100644
index 0000000..388652b
--- /dev/null
+++ b/core/pom.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements. See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership. The ASF licenses this file
+    to you 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <parent>
+        <artifactId>james-project</artifactId>
+        <groupId>org.apache.james</groupId>
+        <version>3.1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>james-core</artifactId>
+
+    <name>Apache James :: Core Domain Objects</name>
+    <description>Provides core domain objects for Email concepts</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-util-java8</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.mail</groupId>
+            <artifactId>javax.mail</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>nl.jqno.equalsverifier</groupId>
+            <artifactId>equalsverifier</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/core/src/main/java/org/apache/james/core/MailAddress.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/james/core/MailAddress.java 
b/core/src/main/java/org/apache/james/core/MailAddress.java
new file mode 100644
index 0000000..54a0f49
--- /dev/null
+++ b/core/src/main/java/org/apache/james/core/MailAddress.java
@@ -0,0 +1,623 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.apache.james.core;
+
+import java.util.Locale;
+
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+
+/**
+ * A representation of an email address.
+ * <p/>
+ * <p>This class encapsulates functionality to access different
+ * parts of an email address without dealing with its parsing.</p>
+ * <p/>
+ * <p>A MailAddress is an address specified in the MAIL FROM and
+ * RCPT TO commands in SMTP sessions.  These are either passed by
+ * an external server to the mailet-compliant SMTP server, or they
+ * are created programmatically by the mailet-compliant server to
+ * send to another (external) SMTP server.  Mailets and matchers
+ * use the MailAddress for the purpose of evaluating the sender
+ * and recipient(s) of a message.</p>
+ * <p/>
+ * <p>MailAddress parses an email address as defined in RFC 821
+ * (SMTP) p. 30 and 31 where addresses are defined in BNF convention.
+ * As the mailet API does not support the aged "SMTP-relayed mail"
+ * addressing protocol, this leaves all addresses to be a {@code <mailbox>},
+ * as per the spec.
+ * <p/>
+ * <p>This class is a good way to validate email addresses as there are
+ * some valid addresses which would fail with a simpler approach
+ * to parsing address. It also removes the parsing burden from
+ * mailets and matchers that might not realize the flexibility of an
+ * SMTP address. For instance, "serge@home"@lokitech.com is a valid
+ * SMTP address (the quoted text serge@home is the local-part and
+ * lokitech.com is the domain). This means all current parsing to date
+ * is incorrect as we just find the first '@' and use that to separate
+ * local-part from domain.</p>
+ * <p/>
+ * <p>This parses an address as per the BNF specification for <mailbox>
+ * from RFC 821 on page 30 and 31, section 4.1.2. COMMAND SYNTAX.
+ * http://www.freesoft.org/CIE/RFC/821/15.htm</p>
+ *
+ * @version 1.0
+ */
+public class MailAddress implements java.io.Serializable {
+    /**
+     * We hardcode the serialVersionUID
+     * This version (2779163542539434916L) retains compatibility back to
+     * Mailet version 1.2 (James 1.2) so that MailAddress will be
+     * deserializable and mail doesn't get lost after an upgrade.
+     */
+    public static final long serialVersionUID = 2779163542539434916L;
+
+    private final static char[] SPECIAL =
+            {'<', '>', '(', ')', '[', ']', '\\', '.', ',', ';', ':', '@', 
'\"'};
+
+    private static final MailAddress NULL_SENDER = new MailAddress() {
+
+        @Override
+        public String getDomain() {
+            return "";
+        }
+
+        @Override
+        public String getLocalPart() {
+            return "";
+        }
+
+        @Override
+        public String toString() {
+            return "";
+        }
+
+        @Override
+        public boolean isNullSender() {
+            return true;
+        }
+
+    };
+
+
+    public static MailAddress nullSender() {
+        return NULL_SENDER;
+    }
+
+    private String localPart = null;
+    private String domain = null;
+
+    private MailAddress() {
+
+    }
+
+    /**
+     * Strips source routing. According to RFC-2821 it is a valid approach
+     * to handle mails containing RFC-821 source-route information.
+     *
+     * @param address the address to strip
+     * @param pos     current position
+     * @return new pos
+     */
+    private int stripSourceRoute(String address, int pos) {
+        if (pos < address.length()) {
+            if (address.charAt(pos) == '@') {
+                int i = address.indexOf(':');
+                if (i != -1) {
+                    pos = i + 1;
+                }
+            }
+        }
+        return pos;
+    }
+
+    /**
+     * Constructs a MailAddress by parsing the provided address.
+     *
+     * @param address the email address, compliant to the RFC2822 3.4.1. 
addr-spec specification
+     * @throws AddressException if the parse failed
+     */
+    public MailAddress(String address) throws AddressException {
+        address = address.trim();
+        int pos = 0;
+
+        // Test if mail address has source routing information (RFC-821) and 
get rid of it!!
+        //must be called first!! (or at least prior to updating pos)
+        stripSourceRoute(address, pos);
+
+        StringBuffer localPartSB = new StringBuffer();
+        StringBuffer domainSB = new StringBuffer();
+        //Begin parsing
+        //<mailbox> ::= <local-part> "@" <domain>
+
+        try {
+            //parse local-part
+            //<local-part> ::= <dot-string> | <quoted-string>
+            if (address.charAt(pos) == '\"') {
+                pos = parseQuotedLocalPartOrThrowException(localPartSB, 
address, pos);
+            } else {
+                pos = parseUnquotedLocalPartOrThrowException(localPartSB, 
address, pos);
+            }
+
+            //find @
+            if (pos >= address.length() || address.charAt(pos) != '@') {
+                throw new AddressException("Did not find @ between local-part 
and domain at position " +
+                        (pos + 1) + " in '" + address + "'", address, pos + 1);
+            }
+            pos++;
+
+            //parse domain
+            //<domain> ::=  <element> | <element> "." <domain>
+            //<element> ::= <name> | "#" <number> | "[" <dotnum> "]"
+            while (true) {
+                if (address.charAt(pos) == '#') {
+                    pos = parseNumber(domainSB, address, pos);
+                } else if (address.charAt(pos) == '[') {
+                    pos = parseDomainLiteral(domainSB, address, pos);
+                } else {
+                    pos = parseDomain(domainSB, address, pos);
+                }
+                if (pos >= address.length()) {
+                    break;
+                }
+                if (address.charAt(pos) == '.') {
+                    char lastChar = address.charAt(pos - 1);
+                    if (lastChar == '@' || lastChar == '.') {
+                        throw new AddressException("Subdomain expected before 
'.' or duplicate '.' in " + address);
+                    }
+                    domainSB.append('.');
+                    pos++;
+                    continue;
+                }
+                break;
+            }
+
+            if (domainSB.toString().length() == 0) {
+                throw new AddressException("No domain found at position " +
+                        (pos + 1) + " in '" + address + "'", address, pos + 1);
+            }
+        } catch (IndexOutOfBoundsException ioobe) {
+            throw new AddressException("Out of data at position " +
+                    (pos + 1) + " in '" + address + "'", address, pos + 1);
+        }
+
+        localPart = localPartSB.toString();
+        domain = domainSB.toString();
+    }
+
+    private int parseUnquotedLocalPartOrThrowException(StringBuffer 
localPartSB, String address, int pos)
+            throws AddressException {
+        pos = parseUnquotedLocalPart(localPartSB, address, pos);
+        if (localPartSB.toString().length() == 0) {
+            throw new AddressException("No local-part (user account) found at 
position " +
+                    (pos + 1) + " in '" + address + "'", address, pos + 1);
+        }
+        return pos;
+    }
+
+    private int parseQuotedLocalPartOrThrowException(StringBuffer localPartSB, 
String address, int pos)
+            throws AddressException {
+        pos = parseQuotedLocalPart(localPartSB, address, pos);
+        if (localPartSB.toString().length() == 2) {
+            throw new AddressException("No quoted local-part (user account) 
found at position " +
+                    (pos + 2) + " in '" + address + "'", address, pos + 2);
+        }
+        return pos;
+    }
+
+    /**
+     * Constructs a MailAddress with the provided local part and domain.
+     *
+     * @param localPart the local-part portion. This is a domain dependent 
string.
+     *                  In addresses, it is simply interpreted on the 
particular host as a
+     *                  name of a particular mailbox. per RFC2822 3.4.1. 
addr-spec specification
+     * @param domain    the domain portion. This identifies the point to which 
the mail
+     *                  is delivered  per RFC2822 3.4.1. addr-spec 
specification
+     * @throws AddressException if the parse failed
+     */
+    public MailAddress(String localPart, String domain) throws 
AddressException {
+        this(new InternetAddress(localPart + "@" + domain));
+    }
+
+    /**
+     * Constructs a MailAddress from an InternetAddress, using only the
+     * email address portion (an "addr-spec", not "name-addr", as
+     * defined in the RFC2822 3.4. Address Specification)
+     *
+     * @param address the address
+     * @throws AddressException if the parse failed
+     */
+    public MailAddress(InternetAddress address) throws AddressException {
+        this(address.getAddress());
+    }
+
+    /**
+     * Returns the host part.
+     *
+     * @return the host part of this email address. If the host is of the
+     *         dotNum form (e.g. [yyy.yyy.yyy.yyy]), then strip the braces 
first.
+     * @deprecated use {@link #getDomain()}, whose name was changed to
+     *             align with RFC2822 3.4.1. addr-spec specification
+     */
+    @Deprecated
+    public String getHost() {
+        return getDomain();
+    }
+
+    /**
+     * Returns the domain part per RFC2822 3.4.1. addr-spec specification.
+     *
+     * @return the domain part of this email address. If the domain is of
+     *         the domain-literal form  (e.g. [yyy.yyy.yyy.yyy]), the braces 
will
+     *         have been stripped returning the raw IP address.
+     * @since Mailet API 2.4
+     */
+    public String getDomain() {
+        if (!(domain.startsWith("[") && domain.endsWith("]"))) {
+            return domain;
+        }
+        return domain.substring(1, domain.length() - 1);
+    }
+
+    /**
+     * Returns the user part.
+     *
+     * @return the user part of this email address
+     * @deprecated use {@link #getLocalPart()}, whose name was changed to
+     *             align with the RFC2822 3.4.1. addr-spec specification
+     */
+    @Deprecated
+    public String getUser() {
+        return getLocalPart();
+    }
+
+    /**
+     * Returns the local-part per RFC2822 3.4.1. addr-spec specification.
+     *
+     * @return the local-part of this email address as defined by the
+     *         RFC2822 3.4.1. addr-spec specification.
+     *         The local-part portion is a domain dependent string.
+     *         In addresses, it is simply interpreted on the particular
+     *         host as a name of a particular mailbox
+     *         (the part before the "@" character)
+     * @since Mailet API 2.4
+     */
+    public String getLocalPart() {
+        return localPart;
+    }
+
+    public String asString() {
+        return localPart + "@" + domain;
+    }
+
+    @Override
+    public String toString() {
+        return localPart + "@" + domain;
+    }
+    
+    public String asPrettyString() {
+        return '<' + asString() + '>';
+    }
+
+    /**
+     * Returns an InternetAddress representing the same address
+     * as this MailAddress.
+     *
+     * @return the address
+     */
+    public InternetAddress toInternetAddress() {
+        try {
+            return new InternetAddress(toString());
+        } catch (javax.mail.internet.AddressException ae) {
+            //impossible really
+            return null;
+        }
+    }
+
+    /**
+     * Indicates whether some other object is "equal to" this one.
+     * <p/>
+     * Note that this implementation breaks the general contract of the
+     * <code>equals</code> method by allowing an instance to equal to a
+     * <code>String</code>. It is recommended that implementations avoid
+     * relying on this design which may be removed in a future release.
+     *
+     * @returns true if the given object is equal to this one, false otherwise
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        } else if (obj instanceof String) {
+            String theString = (String) obj;
+            return toString().equalsIgnoreCase(theString);
+        } else if (obj instanceof MailAddress) {
+            MailAddress addr = (MailAddress) obj;
+            return getLocalPart().equalsIgnoreCase(addr.getLocalPart()) && 
getDomain().equalsIgnoreCase(addr.getDomain());
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this object.
+     * <p/>
+     * This method is implemented by returning the hash code of the canonical
+     * string representation of this address, so that all instances 
representing
+     * the same address will return an identical hash code.
+     *
+     * @return the hashcode.
+     */
+    @Override
+    public int hashCode() {
+        return toString().toLowerCase(Locale.US).hashCode();
+    }
+
+    private int parseQuotedLocalPart(StringBuffer lpSB, String address, int 
pos) throws AddressException {
+        StringBuilder resultSB = new StringBuilder();
+        resultSB.append('\"');
+        pos++;
+        //<quoted-string> ::=  """ <qtext> """
+        //<qtext> ::=  "\" <x> | "\" <x> <qtext> | <q> | <q> <qtext>
+        while (true) {
+            if (address.charAt(pos) == '\"') {
+                resultSB.append('\"');
+                //end of quoted string... move forward
+                pos++;
+                break;
+            }
+            if (address.charAt(pos) == '\\') {
+                resultSB.append('\\');
+                pos++;
+                //<x> ::= any one of the 128 ASCII characters (no exceptions)
+                char x = address.charAt(pos);
+                if (x < 0 || x > 127) {
+                    throw new AddressException("Invalid \\ syntaxed character 
at position " +
+                            (pos + 1) + " in '" + address + "'", address, pos 
+ 1);
+                }
+                resultSB.append(x);
+                pos++;
+            } else {
+                //<q> ::= any one of the 128 ASCII characters except <CR>,
+                //<LF>, quote ("), or backslash (\)
+                char q = address.charAt(pos);
+                if (q <= 0 || q == '\n' || q == '\r' || q == '\"' || q == 
'\\') {
+                    throw new AddressException("Unquoted local-part (user 
account) must be one of the 128 ASCI " +
+                            "characters exception <CR>, <LF>, quote (\"), or 
backslash (\\) at position " +
+                            (pos + 1) + " in '" + address + "'");
+                }
+                resultSB.append(q);
+                pos++;
+            }
+        }
+        lpSB.append(resultSB);
+        return pos;
+    }
+
+    private int parseUnquotedLocalPart(StringBuffer lpSB, String address, int 
pos) throws AddressException {
+        StringBuilder resultSB = new StringBuilder();
+        //<dot-string> ::= <string> | <string> "." <dot-string>
+        boolean lastCharDot = false;
+        while (true) {
+            //<string> ::= <char> | <char> <string>
+            //<char> ::= <c> | "\" <x>
+            if (address.charAt(pos) == '\\') {
+                resultSB.append('\\');
+                pos++;
+                //<x> ::= any one of the 128 ASCII characters (no exceptions)
+                char x = address.charAt(pos);
+                if (x < 0 || x > 127) {
+                    throw new AddressException("Invalid \\ syntaxed character 
at position " + (pos + 1) +
+                            " in '" + address + "'", address, pos + 1);
+                }
+                resultSB.append(x);
+                pos++;
+                lastCharDot = false;
+            } else if (address.charAt(pos) == '.') {
+                if (pos == 0) {
+                    throw new AddressException("Local part must not start with 
a '.'");
+                }
+                resultSB.append('.');
+                pos++;
+                lastCharDot = true;
+            } else if (address.charAt(pos) == '@') {
+                //End of local-part
+                break;
+            } else {
+                //<c> ::= any one of the 128 ASCII characters, but not any
+                //    <special> or <SP>
+                //<special> ::= "<" | ">" | "(" | ")" | "[" | "]" | "\" | "."
+                //    | "," | ";" | ":" | "@"  """ | the control
+                //    characters (ASCII codes 0 through 31 inclusive and
+                //    127)
+                //<SP> ::= the space character (ASCII code 32)
+                char c = address.charAt(pos);
+                if (c <= 31 || c >= 127 || c == ' ') {
+                    throw new AddressException("Invalid character in 
local-part (user account) at position " +
+                            (pos + 1) + " in '" + address + "'", address, pos 
+ 1);
+                }
+                int i = 0;
+                while (i < SPECIAL.length) {
+                    if (c == SPECIAL[i]) {
+                        throw new AddressException("Invalid character in 
local-part (user account) at position " +
+                                (pos + 1) + " in '" + address + "'", address, 
pos + 1);
+                    }
+                    i++;
+                }
+                resultSB.append(c);
+                pos++;
+                lastCharDot = false;
+            }
+        }
+        if (lastCharDot) {
+            throw new AddressException("local-part (user account) ended with a 
\".\", which is invalid in address '" +
+                    address + "'", address, pos);
+        }
+        lpSB.append(resultSB);
+        return pos;
+    }
+
+    private int parseNumber(StringBuffer dSB, String address, int pos) throws 
AddressException {
+        //<number> ::= <d> | <d> <number>
+
+        StringBuilder resultSB = new StringBuilder();
+        // we were passed the string with pos pointing the the # char.
+        // take the first char (#), put it in the result buffer and increment 
pos
+        resultSB.append(address.charAt(pos));
+        pos++;
+        //We keep the position from the class level pos field
+        while (true) {
+            if (pos >= address.length()) {
+                break;
+            }
+            //<d> ::= any one of the ten digits 0 through 9
+            char d = address.charAt(pos);
+            if (d == '.') {
+                break;
+            }
+            if (d < '0' || d > '9') {
+                throw new AddressException("In domain, did not find a number 
in # address at position " +
+                        (pos + 1) + " in '" + address + "'", address, pos + 1);
+            }
+            resultSB.append(d);
+            pos++;
+        }
+        if (resultSB.length() < 2) {
+            throw new AddressException("In domain, did not find a number in # 
address at position " +
+                    (pos + 1) + " in '" + address + "'", address, pos + 1);
+        }
+        dSB.append(resultSB);
+        return pos;
+    }
+
+    private int parseDomainLiteral(StringBuffer dSB, String address, int pos) 
throws AddressException {
+        StringBuilder resultSB = new StringBuilder();
+        //we were passed the string with pos pointing the the [ char.
+        // take the first char ([), put it in the result buffer and increment 
pos
+        resultSB.append(address.charAt(pos));
+        pos++;
+
+        //<dotnum> ::= <snum> "." <snum> "." <snum> "." <snum>
+        for (int octet = 0; octet < 4; octet++) {
+            //<snum> ::= one, two, or three digits representing a decimal
+            //                      integer value in the range 0 through 255
+            //<d> ::= any one of the ten digits 0 through 9
+            StringBuilder snumSB = new StringBuilder();
+            for (int digits = 0; digits < 3; digits++) {
+                char currentChar = address.charAt(pos);
+                if (currentChar == '.' || currentChar == ']') {
+                    break;
+                } else if (currentChar < '0' || currentChar > '9') {
+                    throw new AddressException("Invalid number at position " +
+                            (pos + 1) + " in '" + address + "'", address, pos 
+ 1);
+                }
+                snumSB.append(currentChar);
+                pos++;
+            }
+            if (snumSB.toString().length() == 0) {
+                throw new AddressException("Number not found at position " +
+                        (pos + 1) + " in '" + address + "'", address, pos + 1);
+            }
+            try {
+                int snum = Integer.parseInt(snumSB.toString());
+                if (snum > 255) {
+                    throw new AddressException("Invalid number at position " +
+                            (pos + 1) + " in '" + address + "'", address, pos 
+ 1);
+                }
+            } catch (NumberFormatException nfe) {
+                throw new AddressException("Invalid number at position " +
+                        (pos + 1) + " in '" + address + "'", address, pos + 1);
+            }
+            resultSB.append(snumSB.toString());
+            if (address.charAt(pos) == ']') {
+                if (octet < 3) {
+                    throw new AddressException("End of number reached too 
quickly at " +
+                            (pos + 1) + " in '" + address + "'", address, pos 
+ 1);
+                }
+                break;
+            }
+            if (address.charAt(pos) == '.') {
+                resultSB.append('.');
+                pos++;
+            }
+        }
+        if (address.charAt(pos) != ']') {
+            throw new AddressException("Did not find closing bracket \"]\" in 
domain at position " +
+                    (pos + 1) + " in '" + address + "'", address, pos + 1);
+        }
+        resultSB.append(']');
+        pos++;
+        dSB.append(resultSB);
+        return pos;
+    }
+
+    private int parseDomain(StringBuffer dSB, String address, int pos) throws 
AddressException {
+        StringBuilder resultSB = new StringBuilder();
+        //<name> ::= <a> <ldh-str> <let-dig>
+        //<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
+        //<let-dig> ::= <a> | <d>
+        //<let-dig-hyp> ::= <a> | <d> | "-"
+        //<a> ::= any one of the 52 alphabetic characters A through Z
+        //  in upper case and a through z in lower case
+        //<d> ::= any one of the ten digits 0 through 9
+
+        // basically, this is a series of letters, digits, and hyphens,
+        // but it can't start with a digit or hypthen
+        // and can't end with a hyphen
+
+        // in practice though, we should relax this as domain names can start
+        // with digits as well as letters.  So only check that doesn't start
+        // or end with hyphen.
+        while (true) {
+            if (pos >= address.length()) {
+                break;
+            }
+            char ch = address.charAt(pos);
+            if ((ch >= '0' && ch <= '9') ||
+                    (ch >= 'a' && ch <= 'z') ||
+                    (ch >= 'A' && ch <= 'Z') ||
+                    (ch == '-')) {
+                resultSB.append(ch);
+                pos++;
+                continue;
+            }
+            if (ch == '.') {
+                break;
+            }
+            throw new AddressException("Invalid character at " + pos + " in '" 
+ address + "'", address, pos);
+        }
+        String result = resultSB.toString();
+        if (result.startsWith("-") || result.endsWith("-")) {
+            throw new AddressException("Domain name cannot begin or end with a 
hyphen \"-\" at position " +
+                    (pos + 1) + " in '" + address + "'", address, pos + 1);
+        }
+        dSB.append(result);
+        return pos;
+    }
+
+    /**
+     * Return <code>true</code> if the {@link MailAddress} should represent a 
null sender (<>)
+     *
+     * @return nullsender
+     */
+    public boolean isNullSender() {
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/core/src/test/java/org/apache/james/core/MailAddressTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/james/core/MailAddressTest.java 
b/core/src/test/java/org/apache/james/core/MailAddressTest.java
new file mode 100644
index 0000000..e4438ef
--- /dev/null
+++ b/core/src/test/java/org/apache/james/core/MailAddressTest.java
@@ -0,0 +1,229 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.apache.james.core;
+
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+
+import org.apache.james.core.MailAddress;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class MailAddressTest {
+
+    private static final String
+            GOOD_LOCAL_PART = "\"quoted@local part\"",
+            GOOD_QUOTED_LOCAL_PART = "\"quoted@local part\"@james.apache.org",
+            GOOD_ADDRESS = "server-dev@james.apache.org",
+            GOOD_DOMAIN = "james.apache.org";
+
+    private static final String[] GOOD_ADDRESSES = {
+            GOOD_ADDRESS,
+            GOOD_QUOTED_LOCAL_PART,
+            "server-...@james-apache.org",
+            "server-dev@[127.0.0.1]",
+            "server-dev@#123",
+            "server-dev@#123.apache.org",
+            "server....@james.apache.org",
+            "\\.server-dev@james.apache.org",
+            "server-dev\\.@james.apache.org",
+    };
+
+    private static final String[] BAD_ADDRESSES = {
+            "",
+            "server-dev",
+            "server-dev@",
+            "[]",
+            "server-dev@[]",
+            "server-dev@#",
+            "quoted local-p...@james.apache.org",
+            "quoted@local-p...@james.apache.org",
+            "local-pa...@james.apache.org",
+            ".local-p...@james.apache.org",
+            "local-p...@.james.apache.org",
+            "local-p...@james.apache.org.",
+            "local-p...@james.apache..org",
+            "server-...@-james.apache.org",
+            "server-dev@james.apache.org-",
+            "server-dev@#james.apache.org",
+            "server-dev@#123james.apache.org",
+            "server-dev@#-123.james.apache.org",
+            "server-dev@james. apache.org",
+            "server-dev@james\\.apache.org",
+            "server-dev@[300.0.0.1]",
+            "server-dev@[127.0.1]",
+            "server-dev@[0127.0.0.1]",
+            "server-dev@[127.0.1.1a]",
+            "server-dev@[127\\.0.1.1]",
+            "server-dev@[127.0.1.1.1]",
+            "server-dev@[127.0.1.-1]"
+    };
+
+    /**
+     * Test method for {@link MailAddress#hashCode()}.
+     *
+     * @throws AddressException
+     */
+    @Test
+    public void testHashCode() throws AddressException {
+
+        MailAddress a = new MailAddress(GOOD_ADDRESS);
+        MailAddress b = new MailAddress(GOOD_ADDRESS);
+        Assert.assertTrue(a.hashCode() + " != " + b.hashCode(), a.hashCode() 
== b.hashCode());
+    }
+
+    /**
+     * Test method for {@link MailAddress#MailAddress(java.lang.String)}.
+     *
+     * @throws AddressException
+     */
+    @Test
+    public void testMailAddressString() throws AddressException {
+
+        MailAddress a = new MailAddress(GOOD_ADDRESS);
+        Assert.assertTrue(GOOD_ADDRESS.equals(a.toString()));
+
+        for (String goodAddress : GOOD_ADDRESSES) {
+            try {
+                a = new MailAddress(goodAddress);
+            } catch (AddressException e) {
+                Assert.fail(e.getMessage());
+            }
+        }
+
+        for (String badAddress : BAD_ADDRESSES) {
+            try {
+                a = new MailAddress(badAddress);
+                Assert.fail(badAddress);
+            } catch (AddressException ignore) {
+            }
+        }
+    }
+
+    /**
+     * Test method for {@link MailAddress#MailAddress(java.lang.String, 
java.lang.String)}.
+     */
+    @Test
+    public void testMailAddressStringString() {
+
+        try {
+            new MailAddress("local-part", "domain");
+        } catch (AddressException e) {
+            Assert.assertTrue(e.getMessage(), false);
+        }
+        try {
+            MailAddress a = new MailAddress("local-part", "-domain");
+            Assert.assertFalse(a.toString(), true);
+        } catch (AddressException e) {
+            Assert.assertTrue(true);
+        }
+    }
+
+    /**
+     * Test method for {@link 
MailAddress#MailAddress(javax.mail.internet.InternetAddress)}.
+     */
+    @Test
+    public void testMailAddressInternetAddress() {
+
+        try {
+            new MailAddress(new InternetAddress(GOOD_QUOTED_LOCAL_PART));
+        } catch (AddressException e) {
+            System.out.println("AddressException" + e.getMessage());
+            Assert.assertTrue(e.getMessage(), false);
+        }
+    }
+
+    /**
+     * Test method for {@link MailAddress#getDomain()}.
+     */
+    @Test
+    public void testGetDomain() {
+
+        try {
+            MailAddress a = new MailAddress(new InternetAddress(GOOD_ADDRESS));
+            Assert.assertTrue(a.getDomain() + " != " + GOOD_DOMAIN, 
a.getDomain().equals(GOOD_DOMAIN));
+        } catch (AddressException e) {
+            System.out.println("AddressException" + e.getMessage());
+            Assert.assertTrue(e.getMessage(), false);
+        }
+    }
+
+    /**
+     * Test method for {@link MailAddress#getLocalPart()}.
+     */
+    @Test
+    public void testGetLocalPart() {
+
+        try {
+            MailAddress a = new MailAddress(new 
InternetAddress(GOOD_QUOTED_LOCAL_PART));
+            Assert.assertTrue(GOOD_LOCAL_PART + " != " + a.getLocalPart(), 
a.getLocalPart().equals(GOOD_LOCAL_PART));
+        } catch (AddressException e) {
+            System.out.println("AddressException" + e.getMessage());
+            Assert.assertTrue(e.getMessage(), false);
+        }
+    }
+
+    /**
+     * Test method for {@link MailAddress#toString()}.
+     */
+    @Test
+    public void testToString() {
+
+        try {
+            MailAddress a = new MailAddress(new InternetAddress(GOOD_ADDRESS));
+            Assert.assertTrue(a.toString() + " != " + GOOD_ADDRESS, 
a.toString().equals(GOOD_ADDRESS));
+        } catch (AddressException e) {
+            System.out.println("AddressException" + e.getMessage());
+            Assert.assertTrue(e.getMessage(), false);
+        }
+    }
+
+    /**
+     * Test method for {@link MailAddress#toInternetAddress()}.
+     */
+    @Test
+    public void testToInternetAddress() {
+
+        try {
+            InternetAddress b = new InternetAddress(GOOD_ADDRESS);
+            MailAddress a = new MailAddress(b);
+            Assert.assertTrue(a.toInternetAddress().equals(b));
+            Assert.assertTrue(a.toString() + " != " + GOOD_ADDRESS, 
a.toString().equals(GOOD_ADDRESS));
+        } catch (AddressException e) {
+            System.out.println("AddressException" + e.getMessage());
+            Assert.assertTrue(e.getMessage(), false);
+        }
+    }
+
+    /**
+     * Test method for {@link MailAddress#equals(java.lang.Object)}.
+     *
+     * @throws AddressException
+     */
+    @Test
+    public void testEqualsObject() throws AddressException {
+
+        MailAddress a = new MailAddress(GOOD_ADDRESS);
+        MailAddress b = new MailAddress(GOOD_ADDRESS);
+
+        Assert.assertTrue(a.toString() + " != " + b.toString(), a.equals(b));
+        Assert.assertFalse(a.toString() + " != " + null, a.equals(null));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java
----------------------------------------------------------------------
diff --git 
a/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java 
b/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java
index b96e5a2..5acc119 100644
--- a/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java
+++ b/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java
@@ -34,7 +34,7 @@ import javax.sql.DataSource;
 
 import org.apache.mailet.Experimental;
 import org.apache.mailet.Mail;
-import org.apache.mailet.MailAddress;
+import org.apache.james.core.MailAddress;
 import org.apache.mailet.base.GenericMailet;
 import org.apache.mailet.base.RFC2822Headers;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/mailet/api/pom.xml
----------------------------------------------------------------------
diff --git a/mailet/api/pom.xml b/mailet/api/pom.xml
index 53b4764..e12bd4c 100644
--- a/mailet/api/pom.xml
+++ b/mailet/api/pom.xml
@@ -37,6 +37,10 @@
 
     <dependencies>
         <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>james-core</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.github.steveash.guavate</groupId>
             <artifactId>guavate</artifactId>
         </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/mailet/api/src/main/java/org/apache/mailet/Mail.java
----------------------------------------------------------------------
diff --git a/mailet/api/src/main/java/org/apache/mailet/Mail.java 
b/mailet/api/src/main/java/org/apache/mailet/Mail.java
index 158359a..3339370 100644
--- a/mailet/api/src/main/java/org/apache/mailet/Mail.java
+++ b/mailet/api/src/main/java/org/apache/mailet/Mail.java
@@ -22,6 +22,7 @@ package org.apache.mailet;
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
+import org.apache.james.core.MailAddress;
 import org.apache.mailet.PerRecipientHeaders.Header;
 
 import java.io.Serializable;

http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/mailet/api/src/main/java/org/apache/mailet/MailAddress.java
----------------------------------------------------------------------
diff --git a/mailet/api/src/main/java/org/apache/mailet/MailAddress.java 
b/mailet/api/src/main/java/org/apache/mailet/MailAddress.java
index fbca0a5..0043ac9 100644
--- a/mailet/api/src/main/java/org/apache/mailet/MailAddress.java
+++ b/mailet/api/src/main/java/org/apache/mailet/MailAddress.java
@@ -17,564 +17,24 @@
  * under the License.                                           *
  ****************************************************************/
 
-
 package org.apache.mailet;
 
 import javax.mail.internet.AddressException;
 import javax.mail.internet.InternetAddress;
-import java.util.Locale;
-
-/**
- * A representation of an email address.
- * <p/>
- * <p>This class encapsulates functionality to access different
- * parts of an email address without dealing with its parsing.</p>
- * <p/>
- * <p>A MailAddress is an address specified in the MAIL FROM and
- * RCPT TO commands in SMTP sessions.  These are either passed by
- * an external server to the mailet-compliant SMTP server, or they
- * are created programmatically by the mailet-compliant server to
- * send to another (external) SMTP server.  Mailets and matchers
- * use the MailAddress for the purpose of evaluating the sender
- * and recipient(s) of a message.</p>
- * <p/>
- * <p>MailAddress parses an email address as defined in RFC 821
- * (SMTP) p. 30 and 31 where addresses are defined in BNF convention.
- * As the mailet API does not support the aged "SMTP-relayed mail"
- * addressing protocol, this leaves all addresses to be a {@code <mailbox>},
- * as per the spec.
- * <p/>
- * <p>This class is a good way to validate email addresses as there are
- * some valid addresses which would fail with a simpler approach
- * to parsing address. It also removes the parsing burden from
- * mailets and matchers that might not realize the flexibility of an
- * SMTP address. For instance, "serge@home"@lokitech.com is a valid
- * SMTP address (the quoted text serge@home is the local-part and
- * lokitech.com is the domain). This means all current parsing to date
- * is incorrect as we just find the first '@' and use that to separate
- * local-part from domain.</p>
- * <p/>
- * <p>This parses an address as per the BNF specification for <mailbox>
- * from RFC 821 on page 30 and 31, section 4.1.2. COMMAND SYNTAX.
- * http://www.freesoft.org/CIE/RFC/821/15.htm</p>
- *
- * @version 1.0
- */
-public class MailAddress implements java.io.Serializable {
-    /**
-     * We hardcode the serialVersionUID
-     * This version (2779163542539434916L) retains compatibility back to
-     * Mailet version 1.2 (James 1.2) so that MailAddress will be
-     * deserializable and mail doesn't get lost after an upgrade.
-     */
-    public static final long serialVersionUID = 2779163542539434916L;
-
-    private final static char[] SPECIAL =
-            {'<', '>', '(', ')', '[', ']', '\\', '.', ',', ';', ':', '@', 
'\"'};
 
-    private String localPart = null;
-    private String domain = null;
+@Deprecated
+public class MailAddress extends org.apache.james.core.MailAddress {
 
-    /**
-     * Strips source routing. According to RFC-2821 it is a valid approach
-     * to handle mails containing RFC-821 source-route information.
-     *
-     * @param address the address to strip
-     * @param pos     current position
-     * @return new pos
-     */
-    private int stripSourceRoute(String address, int pos) {
-        if (pos < address.length()) {
-            if (address.charAt(pos) == '@') {
-                int i = address.indexOf(':');
-                if (i != -1) {
-                    pos = i + 1;
-                }
-            }
-        }
-        return pos;
-    }
-
-    /**
-     * Constructs a MailAddress by parsing the provided address.
-     *
-     * @param address the email address, compliant to the RFC2822 3.4.1. 
addr-spec specification
-     * @throws AddressException if the parse failed
-     */
     public MailAddress(String address) throws AddressException {
-        address = address.trim();
-        int pos = 0;
-
-        // Test if mail address has source routing information (RFC-821) and 
get rid of it!!
-        //must be called first!! (or at least prior to updating pos)
-        stripSourceRoute(address, pos);
-
-        StringBuffer localPartSB = new StringBuffer();
-        StringBuffer domainSB = new StringBuffer();
-        //Begin parsing
-        //<mailbox> ::= <local-part> "@" <domain>
-
-        try {
-            //parse local-part
-            //<local-part> ::= <dot-string> | <quoted-string>
-            if (address.charAt(pos) == '\"') {
-                pos = parseQuotedLocalPartOrThrowException(localPartSB, 
address, pos);
-            } else {
-                pos = parseUnquotedLocalPartOrThrowException(localPartSB, 
address, pos);
-            }
-
-            //find @
-            if (pos >= address.length() || address.charAt(pos) != '@') {
-                throw new AddressException("Did not find @ between local-part 
and domain at position " +
-                        (pos + 1) + " in '" + address + "'", address, pos + 1);
-            }
-            pos++;
-
-            //parse domain
-            //<domain> ::=  <element> | <element> "." <domain>
-            //<element> ::= <name> | "#" <number> | "[" <dotnum> "]"
-            while (true) {
-                if (address.charAt(pos) == '#') {
-                    pos = parseNumber(domainSB, address, pos);
-                } else if (address.charAt(pos) == '[') {
-                    pos = parseDomainLiteral(domainSB, address, pos);
-                } else {
-                    pos = parseDomain(domainSB, address, pos);
-                }
-                if (pos >= address.length()) {
-                    break;
-                }
-                if (address.charAt(pos) == '.') {
-                    char lastChar = address.charAt(pos - 1);
-                    if (lastChar == '@' || lastChar == '.') {
-                        throw new AddressException("Subdomain expected before 
'.' or duplicate '.' in " + address);
-                    }
-                    domainSB.append('.');
-                    pos++;
-                    continue;
-                }
-                break;
-            }
-
-            if (domainSB.toString().length() == 0) {
-                throw new AddressException("No domain found at position " +
-                        (pos + 1) + " in '" + address + "'", address, pos + 1);
-            }
-        } catch (IndexOutOfBoundsException ioobe) {
-            throw new AddressException("Out of data at position " +
-                    (pos + 1) + " in '" + address + "'", address, pos + 1);
-        }
-
-        localPart = localPartSB.toString();
-        domain = domainSB.toString();
+        super(address);
     }
 
-    private int parseUnquotedLocalPartOrThrowException(StringBuffer 
localPartSB, String address, int pos)
-            throws AddressException {
-        pos = parseUnquotedLocalPart(localPartSB, address, pos);
-        if (localPartSB.toString().length() == 0) {
-            throw new AddressException("No local-part (user account) found at 
position " +
-                    (pos + 1) + " in '" + address + "'", address, pos + 1);
-        }
-        return pos;
-    }
-
-    private int parseQuotedLocalPartOrThrowException(StringBuffer localPartSB, 
String address, int pos)
-            throws AddressException {
-        pos = parseQuotedLocalPart(localPartSB, address, pos);
-        if (localPartSB.toString().length() == 2) {
-            throw new AddressException("No quoted local-part (user account) 
found at position " +
-                    (pos + 2) + " in '" + address + "'", address, pos + 2);
-        }
-        return pos;
-    }
-
-    /**
-     * Constructs a MailAddress with the provided local part and domain.
-     *
-     * @param localPart the local-part portion. This is a domain dependent 
string.
-     *                  In addresses, it is simply interpreted on the 
particular host as a
-     *                  name of a particular mailbox. per RFC2822 3.4.1. 
addr-spec specification
-     * @param domain    the domain portion. This identifies the point to which 
the mail
-     *                  is delivered  per RFC2822 3.4.1. addr-spec 
specification
-     * @throws AddressException if the parse failed
-     */
     public MailAddress(String localPart, String domain) throws 
AddressException {
-        this(new InternetAddress(localPart + "@" + domain));
+        super(localPart, domain);
     }
 
-    /**
-     * Constructs a MailAddress from an InternetAddress, using only the
-     * email address portion (an "addr-spec", not "name-addr", as
-     * defined in the RFC2822 3.4. Address Specification)
-     *
-     * @param address the address
-     * @throws AddressException if the parse failed
-     */
     public MailAddress(InternetAddress address) throws AddressException {
-        this(address.getAddress());
-    }
-
-    /**
-     * Returns the host part.
-     *
-     * @return the host part of this email address. If the host is of the
-     *         dotNum form (e.g. [yyy.yyy.yyy.yyy]), then strip the braces 
first.
-     * @deprecated use {@link #getDomain()}, whose name was changed to
-     *             align with RFC2822 3.4.1. addr-spec specification
-     */
-    @Deprecated
-    public String getHost() {
-        return getDomain();
-    }
-
-    /**
-     * Returns the domain part per RFC2822 3.4.1. addr-spec specification.
-     *
-     * @return the domain part of this email address. If the domain is of
-     *         the domain-literal form  (e.g. [yyy.yyy.yyy.yyy]), the braces 
will
-     *         have been stripped returning the raw IP address.
-     * @since Mailet API 2.4
-     */
-    public String getDomain() {
-        if (!(domain.startsWith("[") && domain.endsWith("]"))) {
-            return domain;
-        }
-        return domain.substring(1, domain.length() - 1);
-    }
-
-    /**
-     * Returns the user part.
-     *
-     * @return the user part of this email address
-     * @deprecated use {@link #getLocalPart()}, whose name was changed to
-     *             align with the RFC2822 3.4.1. addr-spec specification
-     */
-    @Deprecated
-    public String getUser() {
-        return getLocalPart();
-    }
-
-    /**
-     * Returns the local-part per RFC2822 3.4.1. addr-spec specification.
-     *
-     * @return the local-part of this email address as defined by the
-     *         RFC2822 3.4.1. addr-spec specification.
-     *         The local-part portion is a domain dependent string.
-     *         In addresses, it is simply interpreted on the particular
-     *         host as a name of a particular mailbox
-     *         (the part before the "@" character)
-     * @since Mailet API 2.4
-     */
-    public String getLocalPart() {
-        return localPart;
+        super(address);
     }
 
-    public String asString() {
-        return localPart + "@" + domain;
-    }
-
-    @Override
-    public String toString() {
-        return localPart + "@" + domain;
-    }
-    
-    public String asPrettyString() {
-        return '<' + asString() + '>';
-    }
-
-    /**
-     * Returns an InternetAddress representing the same address
-     * as this MailAddress.
-     *
-     * @return the address
-     */
-    public InternetAddress toInternetAddress() {
-        try {
-            return new InternetAddress(toString());
-        } catch (javax.mail.internet.AddressException ae) {
-            //impossible really
-            return null;
-        }
-    }
-
-    /**
-     * Indicates whether some other object is "equal to" this one.
-     * <p/>
-     * Note that this implementation breaks the general contract of the
-     * <code>equals</code> method by allowing an instance to equal to a
-     * <code>String</code>. It is recommended that implementations avoid
-     * relying on this design which may be removed in a future release.
-     *
-     * @returns true if the given object is equal to this one, false otherwise
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        } else if (obj instanceof String) {
-            String theString = (String) obj;
-            return toString().equalsIgnoreCase(theString);
-        } else if (obj instanceof MailAddress) {
-            MailAddress addr = (MailAddress) obj;
-            return getLocalPart().equalsIgnoreCase(addr.getLocalPart()) && 
getDomain().equalsIgnoreCase(addr.getDomain());
-        }
-        return false;
-    }
-
-    /**
-     * Returns a hash code value for this object.
-     * <p/>
-     * This method is implemented by returning the hash code of the canonical
-     * string representation of this address, so that all instances 
representing
-     * the same address will return an identical hash code.
-     *
-     * @return the hashcode.
-     */
-    @Override
-    public int hashCode() {
-        return toString().toLowerCase(Locale.US).hashCode();
-    }
-
-    private int parseQuotedLocalPart(StringBuffer lpSB, String address, int 
pos) throws AddressException {
-        StringBuilder resultSB = new StringBuilder();
-        resultSB.append('\"');
-        pos++;
-        //<quoted-string> ::=  """ <qtext> """
-        //<qtext> ::=  "\" <x> | "\" <x> <qtext> | <q> | <q> <qtext>
-        while (true) {
-            if (address.charAt(pos) == '\"') {
-                resultSB.append('\"');
-                //end of quoted string... move forward
-                pos++;
-                break;
-            }
-            if (address.charAt(pos) == '\\') {
-                resultSB.append('\\');
-                pos++;
-                //<x> ::= any one of the 128 ASCII characters (no exceptions)
-                char x = address.charAt(pos);
-                if (x < 0 || x > 127) {
-                    throw new AddressException("Invalid \\ syntaxed character 
at position " +
-                            (pos + 1) + " in '" + address + "'", address, pos 
+ 1);
-                }
-                resultSB.append(x);
-                pos++;
-            } else {
-                //<q> ::= any one of the 128 ASCII characters except <CR>,
-                //<LF>, quote ("), or backslash (\)
-                char q = address.charAt(pos);
-                if (q <= 0 || q == '\n' || q == '\r' || q == '\"' || q == 
'\\') {
-                    throw new AddressException("Unquoted local-part (user 
account) must be one of the 128 ASCI " +
-                            "characters exception <CR>, <LF>, quote (\"), or 
backslash (\\) at position " +
-                            (pos + 1) + " in '" + address + "'");
-                }
-                resultSB.append(q);
-                pos++;
-            }
-        }
-        lpSB.append(resultSB);
-        return pos;
-    }
-
-    private int parseUnquotedLocalPart(StringBuffer lpSB, String address, int 
pos) throws AddressException {
-        StringBuilder resultSB = new StringBuilder();
-        //<dot-string> ::= <string> | <string> "." <dot-string>
-        boolean lastCharDot = false;
-        while (true) {
-            //<string> ::= <char> | <char> <string>
-            //<char> ::= <c> | "\" <x>
-            if (address.charAt(pos) == '\\') {
-                resultSB.append('\\');
-                pos++;
-                //<x> ::= any one of the 128 ASCII characters (no exceptions)
-                char x = address.charAt(pos);
-                if (x < 0 || x > 127) {
-                    throw new AddressException("Invalid \\ syntaxed character 
at position " + (pos + 1) +
-                            " in '" + address + "'", address, pos + 1);
-                }
-                resultSB.append(x);
-                pos++;
-                lastCharDot = false;
-            } else if (address.charAt(pos) == '.') {
-                if (pos == 0) {
-                    throw new AddressException("Local part must not start with 
a '.'");
-                }
-                resultSB.append('.');
-                pos++;
-                lastCharDot = true;
-            } else if (address.charAt(pos) == '@') {
-                //End of local-part
-                break;
-            } else {
-                //<c> ::= any one of the 128 ASCII characters, but not any
-                //    <special> or <SP>
-                //<special> ::= "<" | ">" | "(" | ")" | "[" | "]" | "\" | "."
-                //    | "," | ";" | ":" | "@"  """ | the control
-                //    characters (ASCII codes 0 through 31 inclusive and
-                //    127)
-                //<SP> ::= the space character (ASCII code 32)
-                char c = address.charAt(pos);
-                if (c <= 31 || c >= 127 || c == ' ') {
-                    throw new AddressException("Invalid character in 
local-part (user account) at position " +
-                            (pos + 1) + " in '" + address + "'", address, pos 
+ 1);
-                }
-                int i = 0;
-                while (i < SPECIAL.length) {
-                    if (c == SPECIAL[i]) {
-                        throw new AddressException("Invalid character in 
local-part (user account) at position " +
-                                (pos + 1) + " in '" + address + "'", address, 
pos + 1);
-                    }
-                    i++;
-                }
-                resultSB.append(c);
-                pos++;
-                lastCharDot = false;
-            }
-        }
-        if (lastCharDot) {
-            throw new AddressException("local-part (user account) ended with a 
\".\", which is invalid in address '" +
-                    address + "'", address, pos);
-        }
-        lpSB.append(resultSB);
-        return pos;
-    }
-
-    private int parseNumber(StringBuffer dSB, String address, int pos) throws 
AddressException {
-        //<number> ::= <d> | <d> <number>
-
-        StringBuilder resultSB = new StringBuilder();
-        // we were passed the string with pos pointing the the # char.
-        // take the first char (#), put it in the result buffer and increment 
pos
-        resultSB.append(address.charAt(pos));
-        pos++;
-        //We keep the position from the class level pos field
-        while (true) {
-            if (pos >= address.length()) {
-                break;
-            }
-            //<d> ::= any one of the ten digits 0 through 9
-            char d = address.charAt(pos);
-            if (d == '.') {
-                break;
-            }
-            if (d < '0' || d > '9') {
-                throw new AddressException("In domain, did not find a number 
in # address at position " +
-                        (pos + 1) + " in '" + address + "'", address, pos + 1);
-            }
-            resultSB.append(d);
-            pos++;
-        }
-        if (resultSB.length() < 2) {
-            throw new AddressException("In domain, did not find a number in # 
address at position " +
-                    (pos + 1) + " in '" + address + "'", address, pos + 1);
-        }
-        dSB.append(resultSB);
-        return pos;
-    }
-
-    private int parseDomainLiteral(StringBuffer dSB, String address, int pos) 
throws AddressException {
-        StringBuilder resultSB = new StringBuilder();
-        //we were passed the string with pos pointing the the [ char.
-        // take the first char ([), put it in the result buffer and increment 
pos
-        resultSB.append(address.charAt(pos));
-        pos++;
-
-        //<dotnum> ::= <snum> "." <snum> "." <snum> "." <snum>
-        for (int octet = 0; octet < 4; octet++) {
-            //<snum> ::= one, two, or three digits representing a decimal
-            //                      integer value in the range 0 through 255
-            //<d> ::= any one of the ten digits 0 through 9
-            StringBuilder snumSB = new StringBuilder();
-            for (int digits = 0; digits < 3; digits++) {
-                char currentChar = address.charAt(pos);
-                if (currentChar == '.' || currentChar == ']') {
-                    break;
-                } else if (currentChar < '0' || currentChar > '9') {
-                    throw new AddressException("Invalid number at position " +
-                            (pos + 1) + " in '" + address + "'", address, pos 
+ 1);
-                }
-                snumSB.append(currentChar);
-                pos++;
-            }
-            if (snumSB.toString().length() == 0) {
-                throw new AddressException("Number not found at position " +
-                        (pos + 1) + " in '" + address + "'", address, pos + 1);
-            }
-            try {
-                int snum = Integer.parseInt(snumSB.toString());
-                if (snum > 255) {
-                    throw new AddressException("Invalid number at position " +
-                            (pos + 1) + " in '" + address + "'", address, pos 
+ 1);
-                }
-            } catch (NumberFormatException nfe) {
-                throw new AddressException("Invalid number at position " +
-                        (pos + 1) + " in '" + address + "'", address, pos + 1);
-            }
-            resultSB.append(snumSB.toString());
-            if (address.charAt(pos) == ']') {
-                if (octet < 3) {
-                    throw new AddressException("End of number reached too 
quickly at " +
-                            (pos + 1) + " in '" + address + "'", address, pos 
+ 1);
-                }
-                break;
-            }
-            if (address.charAt(pos) == '.') {
-                resultSB.append('.');
-                pos++;
-            }
-        }
-        if (address.charAt(pos) != ']') {
-            throw new AddressException("Did not find closing bracket \"]\" in 
domain at position " +
-                    (pos + 1) + " in '" + address + "'", address, pos + 1);
-        }
-        resultSB.append(']');
-        pos++;
-        dSB.append(resultSB);
-        return pos;
-    }
-
-    private int parseDomain(StringBuffer dSB, String address, int pos) throws 
AddressException {
-        StringBuilder resultSB = new StringBuilder();
-        //<name> ::= <a> <ldh-str> <let-dig>
-        //<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
-        //<let-dig> ::= <a> | <d>
-        //<let-dig-hyp> ::= <a> | <d> | "-"
-        //<a> ::= any one of the 52 alphabetic characters A through Z
-        //  in upper case and a through z in lower case
-        //<d> ::= any one of the ten digits 0 through 9
-
-        // basically, this is a series of letters, digits, and hyphens,
-        // but it can't start with a digit or hypthen
-        // and can't end with a hyphen
-
-        // in practice though, we should relax this as domain names can start
-        // with digits as well as letters.  So only check that doesn't start
-        // or end with hyphen.
-        while (true) {
-            if (pos >= address.length()) {
-                break;
-            }
-            char ch = address.charAt(pos);
-            if ((ch >= '0' && ch <= '9') ||
-                    (ch >= 'a' && ch <= 'z') ||
-                    (ch >= 'A' && ch <= 'Z') ||
-                    (ch == '-')) {
-                resultSB.append(ch);
-                pos++;
-                continue;
-            }
-            if (ch == '.') {
-                break;
-            }
-            throw new AddressException("Invalid character at " + pos + " in '" 
+ address + "'", address, pos);
-        }
-        String result = resultSB.toString();
-        if (result.startsWith("-") || result.endsWith("-")) {
-            throw new AddressException("Domain name cannot begin or end with a 
hyphen \"-\" at position " +
-                    (pos + 1) + " in '" + address + "'", address, pos + 1);
-        }
-        dSB.append(result);
-        return pos;
-    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/mailet/api/src/main/java/org/apache/mailet/MailetContext.java
----------------------------------------------------------------------
diff --git a/mailet/api/src/main/java/org/apache/mailet/MailetContext.java 
b/mailet/api/src/main/java/org/apache/mailet/MailetContext.java
index 2b2dd96..202caf7 100644
--- a/mailet/api/src/main/java/org/apache/mailet/MailetContext.java
+++ b/mailet/api/src/main/java/org/apache/mailet/MailetContext.java
@@ -27,6 +27,7 @@ import java.util.List;
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
+import org.apache.james.core.MailAddress;
 import org.slf4j.Logger;
 
 /**

http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/mailet/api/src/main/java/org/apache/mailet/Matcher.java
----------------------------------------------------------------------
diff --git a/mailet/api/src/main/java/org/apache/mailet/Matcher.java 
b/mailet/api/src/main/java/org/apache/mailet/Matcher.java
index a444a84..3d71072 100644
--- a/mailet/api/src/main/java/org/apache/mailet/Matcher.java
+++ b/mailet/api/src/main/java/org/apache/mailet/Matcher.java
@@ -23,6 +23,8 @@ package org.apache.mailet;
 import java.util.Collection;
 import javax.mail.MessagingException;
 
+import org.apache.james.core.MailAddress;
+
 /**
  * This interface defines the behaviour of the message "routing" inside
  * the mailet container. At its heart is the {@link #match(Mail)} method,

http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java
----------------------------------------------------------------------
diff --git 
a/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java 
b/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java
index af9b233..0b7bcdb 100644
--- a/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java
+++ b/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java
@@ -21,6 +21,8 @@ package org.apache.mailet;
 
 import java.util.Collection;
 
+import org.apache.james.core.MailAddress;
+
 import com.github.steveash.guavate.Guavate;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.MoreObjects;


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org
For additional commands, e-mail: server-dev-h...@james.apache.org

Reply via email to