Software Reality
Programming with
a dose of satire.

Site Map Search


Agile Development
 
Extreme Programming
 
Code Generation


Articles
Lifecycle
Design
Programming
Soapbox
Reviews
Cthulhu

Java Swing
Swing's greatest threat isn't SWT, it's Flash
Swing Survival Guide


 
Check out our ageing Reviews Section


Use Case Driven
Use Case Driven Object Modeling with UML: Theory and Practice
Get from use cases to working, maintainable source code. Examples use Spring Framework, JUnit and Enterprise Architect

Agile UML
Agile Development with ICONIX Process
A practical subset of agile development techniques, illustrated by example

Get Controversial!
Extreme Programming Refactored
Extreme Programming with a dose of satire
Available now:



Programming

Annotations: Don't Mess with Java

By Robin Sharp
August 18, 2005

 

Annotations are a major kludge on the landscape. They don't fit and we don't need them; but you just know that they'll be picked up by framework junkies and abused horribly.

Every so often Sun appears to let out a really big howler. Take EJB 1 and 2. The justification for distributed object transactions was an aberration brought about by the influence of the CORBA object framework-geeks. It’s taken them years to even start to recover from that mistake. The success of Hibernate was needed to show that the folks at Sun got it wrong. EJB cost the industry many billions of pounds in lost development time. However, like Dorothy’s Ruby slippers, the solution was right under their nose all along, in the form of JavaBeans, local O-R mapping, remote sessions and XA transactions.

Another Big Howler

They now appear to have made another really big howler in the form of annotations. Given the strong dependency EJB 3 has on annotations, I guess the EJB design mentality has been allowed to pollute the core Java language. Am I the only one to notice? It’s so obvious. In fact it’s so obvious that you may have some time adjusting to the idea.

Annotations are not MetaData . . .

Sun talks of annotations as being an extension to the existing metadata in Java. I disagree. Let’s define metadata. Metadata is data about data. I consider the reflection API as something that expresses metadata. It tells you about classes and their methods. It tells you about the types of arguments in your methods. It tells you about the structure of your pre-existing Java code.

. . . annotations are "DecorativeData"

Annotations tell you nothing about your Java code, they tell you nothing about the instances of your Java classes, methods or fields. However they supply additional properties about your Java classes, methods or fields. They're meant to supply additional data about how the software is to be compiled, deployed or executed. This is not metadata, it’s decorative data.

Annotations are hard coded configurations

It’s so pervasive that I hardly need repeat it. How many times have you had to make that extra push to ensure that a parameter is not hard coded? It’s such an important principle that we sometimes overdo it.

However, when I look at an annotation like this it makes me shake my head: -

@Resource(name="myDB", type="javax.sql.DataSource.class")
@Table(name="CUST", schema="RECORDS")

We have all had to live with the problem in the previous versions of EJB of having to rebuild and re-deploy an application just to change the JDBC configuration. In the large corporate projects I work on, there are multiple database vendors and multiple schemas being used. It’s a long, slow painful process having to edit the XML and re-deploy. The annotation solution appears to have worsened these problems because the JDBC configuration is now embedded in the Java code itself. Ask yourself this simple question: I have two stubborn clients with different table names for the same beans... is the deployment solution elegant?

Annotations do Not Replace XML

Annotations were supposed to be a replacement to XML. The reason was that XML re-introduced all those knives and daggers, that Gosling rightly disliked about C++. But the XML in Enterprise Beans has not gone away. Now we’ve got configuration in the Java code as well.

Annotations are Litter

This is a weaker point but it allows me to introduce an analogy. Annotations are litter and will eventually litter our code. I can see some kind of annotation folding being introduced into the Java development environments in double quick time.

Annotations are a Kludge

Even in the most favourable light you have to admit that the implementation of annotations is a kludge. I don’t blame the people that designed the implementation, because annotations are not a natural fit into the Java architecture. As hard as Sun's engineers tried, you can’t call the @interface code elegant. Kludges in code are like kludges in theories: they reveal an underlying mismatch between human artefacts and the nature of things.

.NET led Annotations

Annotations are primarily a response to .NET annotations. They are a solution looking for an problem. I think the folks at Sun meant Java 5 to be a response to .NET, along with the introduction of generics, the enumeration type and boxed types. I’m not knocking the other new language constructs; I think they are a great addition and well implemented.

Begging for Abuse

In the book The Design and Evolution of C++, it's clear that Stroustrup was careful not to introduce features into C++ that could be open to abuse. Stroustrup was over cautious, not introducing metadata because he thought it would be abused. I think he’s been proved wrong about that. Annotations are, however, a different case because they are so open in scope. I don’t think I’ll be proved wrong about annotations. Their one saving grace is that they are a kludge, difficult to implement, and hopefully won’t become ubiquitous in application code. But I expect the same framework-geeks that drove to be thoughtlessly expecting application developers to pick their litter up.

Annotations will Evolve

Lets suppose that annotations do become abused, as I expect. How are we going to control them? As annotations evolve and best practices appear, I expect somebody will come up with a more formal enforcement.

A Better Solution

I’d see a case for replacing XML, and annotations. Annotations will be seen as litter on the Java landscape. One thing that strikes me about the move from XML to annotations is the shift from having a many-one relationship between code and XML to a one-one relationship between code and annotations, as well as the move from weakly-typed to more strongly-typed enforced configuration. I believe that there is a better intermediate solution that keeps a many-one relationship between code and XML as well as strongly typed configuration.

A better solution for Sun would have been to come up with an XML-like structure that could be coded into Java. This would give all the benefits of rigorous type enforcement, and the benefits of a many-one relationship between code and configuration, and the benefits of separating the configuration data out of business objects.

I would see these XML structures as being defined by something with similar semantics to XML schemas, but they would be implemented something like nested static classes containing defaults. When I look at the XML schema semantics and extended Java nested static classes, they do seem like they have similar semantics.

Extended nested static classes would provide type safety. They could be overridden by specific implementations. They could be available to introspection. Configuration would be kept in Java. I believe it would be worth exploring extending the semantics of Java nested static classes to do the job of XML configurations in a more rigorous manner than annotations provide.

What went Wrong?

When the folks at Sun start looking over the garden fence at their rivals, they get sucked into playing them at their game, and not their own. It happened with EJB and it’s happened with annotations. This is not leadership and it is not innovation. It’s not what Java developers need.

 

 

Your Comments

Post a new message

Message Index:

We must be careful.
Regis Santos

I disagree
John

Nice rant, but try again.
Greg greg_barton@yahoo.com

Ridiculous argument
Anonymous person

Annotations do not preclude the use of XML
Richard

In defense of annotations
Dhananjay Nene

No native XML in java code!
cowardly dragon

Unconvincing examples
Gavin King

A case for Annotations
Annotations Rule

Yes and No
Richard richardqr@gmail.com

Why not use the Java language to do configuration ???
Sergio Oliveira sergio.oliveira.jr@gmail.com

Another case for Annotations...
Fábio A. Falavinha

You know, as soon as I saw annotations I had this sinking feeling...
Will william.chamberlain@gmail.com

Classical FUD
Lou

+1
Vic netsql at roomity.com

Annotations ARE bad
Jan Hansen

Wrong assumption
Anonymous person

Interesting critique
Josh Allen joshuaallen@wildmail.com

Re: Nice rant, but try again.
Robert Jones robert@harpswell.com

You will eat your words
Ron Pakston bmxbandit@yahoo.com

Good argument. Specially about 1 x N + strong types
Steven steven_patrick_df@hotmail.com

Babel, Gas-Plant and Mermaids
Thierry thanser@noos.fr

You know what I'd like?
Paul Murray pmurray@bigpond.com

hmm, there's some interesting points here, it's worth thinking about, right? th ...
Dan Moore

so much bad gas
noj nojo@gmail.com

they are meta data
Anonymous person

Dispersed Semantics?
Simon

Code Maintenance
demi

More freedom more fun
Alexander

The Messages:
We must be careful.
Hello Robin,

You can do good things or bad things in your code. It can be in Java, in .Net or C++. Annotations could be a mess if we wouldn't know how to use it.


Regis Santos
Fortaleza - CE, Brazil

Tue Aug 23 13:03:32 BST 2005
I disagree
I disagree with your opinion that annotations are bad.
You are right that for data that is meant to be configurable you should better not use annotations (e.g. usernames, hostnames, passwords). But for application internal concerns annotations are a real salvation.
Look at EJB3 persistence. Whats wrong with specifying a class as an persistable entity or a field as a persitable field using annotations. Using XML descriptors such things simply sucks. Annotations allows you to stay within the programming language of choice and also don't get lost/broken when you have to refactor your code a lot. It is with all other language features, you as a developer can mess everything up by using them wrong. Therefor you should write your code carefully.
If there are things that might be required to be changed/configured later you can a) additionally provide a mechanism to override the default settings made as annotations or b) only use config files for these separate settings.

John

John

Tue Aug 23 14:08:33 BST 2005
Nice rant, but try again.
Want XML based metadata?

Have annotatios of this form:
@XMLAnnotation(xml="<foo><bar>bas!</bar></foo>")

Then use AspectJ5 to statically check the XML for compliance with a dtd.

"Annotations were supposed to be a replacement to XML."

Annotations are a replacement for configuration seperated from code, not just XML. Your vision is too narrow. Annotations do provide a replacement for configuration, but frankly that's their weakest use.

And, as for your "stubborn clients" example, use your imagination. Off the top of my head, this solution: abstract subclasses of your beans containing all code, with concrete implementations that are annotated with the proper configuration. Complex? Just as complex as having seperate config files for each client, with the added benefit that modifications can be checked by the compiler.

"I consider the reflection API as something that expresses metadata."

You're wrong. The reflection API is a way to discover the structure of java code. It provides no way to add additional descriptions of the structures. (i.e. meta data, or data about the data) Annotations allow the programmer to add these descriptions. And they are are accesible to reflection. What do you think Class.getAnnotation(), Field.getAnnotation(), and Method.getAnnotation() are for?

Greg greg_barton@yahoo.com
Dallas, Texas, USA

Tue Aug 23 17:44:11 BST 2005
Ridiculous argument
There are bad ways to use annotations just like there are bad ways to use exceptions. The example you give of putting db configuration in an annotation is one of those bad ways! I agree that unfortunately there will be people who abuse them in this way but they'll abuse any language in all sorts of ways.

Annotations are great in the same way interfaces are great - for indicating additional capabilities/constraints of an object/method/etc.

Anonymous person

Wed Aug 24 05:01:47 BST 2005
Annotations do not preclude the use of XML
From...

http://today.java.net/pub/a/today/2005/08/18/ejb3.html

...talking about EJB3:

"This doesn't mean that XML has been completely removed; it's now optional. If we define both a deployment descriptor and annotations, the deployment descriptor overrides the annotations."

Richard

Wed Aug 24 05:28:42 BST 2005
In defense of annotations
Posted a defense @ http://dnene.com/archives/8
Dhananjay Nene

Wed Aug 24 16:39:18 BST 2005
No native XML in java code!
No XML in java code. Don't do it.

XML is ugly and people are constantly trying to replace it with other data structures in more compact or powerful forms.

GroovyMarkup is as far as java should go. A means for constructing a tree without the cumbersome XML syntax, verbose end tags, and punctuation.

cowardly dragon
midwest

Wed Aug 24 16:56:55 BST 2005
Unconvincing examples
So, let's look at the actual two *concrete* examples of supposed Badness due to annotations. First:

@Resource(name="myDB", type="javax.sql.DataSource.class")

Well, I don't know what type is doing there, since it is guessable from the instvar type, so this *should* be:

@Resource(name="myDB")

How is that "configuration"?? "MyDB" is a *logical name* of a logical source of data for the application! No-one is arguing that this should be:

@Resource(url="jdbc:db2:myDB")

And no-one is using annotations in this way. So what's the problem? What in hell is the difference between the annotated way and:

new InitialContext().lookup("myDB")

Which is how most people do it now?


OK, second example:

@Table(name="CUST", schema="RECORDS")

Well, personally I am not crash-hot on embedded schema names in mappings at all, either in XML or annotations! So, I can see a minor objection to the schema being there. So I would write:

@Table(name="CUST")

Now, what on earth is wrong with that? I mean, a lot of people hardcode actual *SQL statements* into strings in their Java code! How is this worse than DAOs with embedded SQL strings?

In what reasonable scenarios does the name of a *table* that is central to the data model of your organization change between different deployments of the system? Realistically it does not. Realistically, the names of tables in your database change MUCH less often than the Java code that accesses it. So I'm pretty sure that the class gets renamed more often than the value of that annotation changes.

Looks good to me, frankly. I notice a *lot* of people have been happy doing that with XDoclet for years, and now love Hibernate Annotations even more.


So I guess I'm still waiting for a really convincing example of "annotation abuse".

Gavin King

Wed Aug 24 18:01:51 BST 2005
A case for Annotations
You can not prevent miss or over using of anything feature. I personally like annotations because it keeps my "application" as a whole very simple.
No body likes to "litter" their code. Annotations are certainly not litter to me. Infact they help keeping things POJO.

I completely disagree with this argument that Annotations are not good. If you don't like using annotations don't use them, that's the beauty of annotations. Annotations are about coding "freely" without worring about where the code is going to live ( J2EE container, Web services , hand held devices or washing machines, cars).

Annotations Rule

Thu Aug 25 04:35:20 BST 2005
Yes and No
Yes, annotations can be abused, just like any other part of Java.

No, annotations is there to help. It can't pass JCP if it ain't good. Annotations can help Java to be as POJO as it can be.

Richard richardqr@gmail.com
Singapore

Thu Aug 25 06:35:10 BST 2005
Why not use the Java language to do configuration ???
Check this:

http://mentawai.lohis.com.br/

to understand what I mean.

Sergio Oliveira sergio.oliveira.jr@gmail.com
Rio de Janeiro, Brazil

Thu Aug 25 15:55:39 BST 2005
Another case for Annotations...
Another case to Annotations, it's put together with AOP.
Read this out of the box:
http://www.onjava.com/pub/a/onjava/2004/06/30/insidebox1.html?page=1

Fábio A. Falavinha
Brazil

Fri Aug 26 18:28:06 BST 2005
You know, as soon as I saw annotations I had this sinking feeling...
Is it just me, or does anyone else feel that as far as possible configuration doesn't belong in the code?

I mean, yes, fair enough; you have to get your resources somehow, but why on earth do you want to invent such a weird syntax to replace a few lines of code with a few lines of annotations? If it's bootstrapping that has to go in the class, write it in code. If it can be separated from the class to be loaded at runtime, stick it into a configuration file. If there was a decent DTD-aware config-file manipulator built into IDEs writing config files wouldn't be a problem, but instead they'll all be running to put annotation support in.

Look at it this way: after changing a configuration file I just have to jar the application; after changing an annotation I have to recompile, which means that I should re-run my tests. Configuration files are loosely-coupled at runtime, annotations are tightly-coupled at compile-time and therefore not a lot more efficient and definitely a lot uglier that plain code.

Note that I don't have a particular problem with annotations used to decorate code for specific purposes. But I do feel that there is going to be a lot of bad code written, particularly given the huge scope of fariy dust invention available with annotations.

Will william.chamberlain@gmail.com
Brisbane, Australia

Mon Aug 29 13:31:46 BST 2005
Classical FUD
This article is classical fear of change. It happened with C to C++ to Java to AOP, etc. People generally resist change and this article is case and point.

If you don't like annotations, don't use them! You still have the ability to write without them. For the rest that are willing to embrace change, welcome to convenience of annotations.

Lou

Lou
US

Sat Sep 03 20:17:16 BST 2005
+1
I agree.
http://forums.java.net/jive/thread.jspa?threadID=1316&tstart=0

.V
http://roomity.com

Vic netsql at roomity.com
DFW

Sun Sep 04 22:51:05 BST 2005
Annotations ARE bad
"If you don't like them don't use them." is not a valid argument in my opinion.
"If you don't like guns don't use them." don't make much sense either. Problem is when I have little or no influence upon whether things I dislike are "forced" upon me.

Annotations & autoboxing are a mistake, but it is unlikely we will ever get rid of them.

Jan Hansen
Copenhagen, Denmark

Tue Sep 06 14:31:11 BST 2005
Wrong assumption
Read some theory man: Metadata = information about data and not data about data.
In information theory, information <> data. That fine distinction blows entirely your article.

Anonymous person

Fri Dec 02 17:58:56 GMT 2005
Interesting critique
I think a more tangible benifit of annotations will prove to be reducing boiler-plate and cookie cutter code. Hardcoding configuration information is still best done with a properties or xml file.. but that doesn't mean you can't use annotations to specify what dependancies it has.

I don't understand the problem you are trying to solve with the native XML support with type-safety (?), would need an example I think.

Josh Allen joshuaallen@wildmail.com
Parkdale, Toronto

Thu Jun 22 04:20:55 BST 2006
Re: Nice rant, but try again.
"Want XML based metadata?

Have annotatios of this form:
@XMLAnnotation(xml="<foo><bar>bas!</bar></foo>")

Then use AspectJ5 to statically check the XML for compliance with a dtd."

Right, brilliant solution - tack on another kludge over an existing kludge.


Robert Jones robert@harpswell.com
Upper midwest, U.S.

Tue Aug 15 16:45:20 BST 2006
You will eat your words
I don't like it when people fear change.

The author of this article fears change.

Let's all just sit back and say :

We are happy with what we have, and lets not touch it.

What a DOOS........

Ron Pakston bmxbandit@yahoo.com
za, za

Wed Oct 11 15:58:14 BST 2006
Good argument. Specially about 1 x N + strong types
I simply can't suppose all these angry commenters even read your text.
At least they CANNOT doubt you're RIGHT about an obviously better solution...

As you said, I also
"believe that there is a better intermediate solution that keeps a many-one relationship between code and XML as well as strongly typed configuration."

Steven steven_patrick_df@hotmail.com
Brasil

Wed Nov 01 02:15:03 GMT 2006
Babel, Gas-Plant and Mermaids
Robin's overview of the threat of JAVA annotation is very interesting. It highlights most of the issues of annotations. I agree on every point Robin is presenting. Annotation is a very weak and potentialy harmful extension of JAVA

In addition to Robins's points I would like to add the followings:

o Java code using annotation can be syntactically compiled but not semantically interpreted by a standard java compiler. In other word the code belongs to a new implicit "pseudo" language defined by the mixture of java and all the annotation schema used in this code. As a result we will face a combinatorial explosion of pseudo languages based on JAVA + annotation schemas X,Y, Z, but also X and Y , X and Z,etc. Such an evolution of JAVA annotated code will inevitably lead to a BABEL syndrom !

o Extending the semantic of a language with just a syntactic twick is a weak and abuse-prone approach. It is a common pitfal when designing languages. The solution might seem very flexible and easy to use but with consequences behond the control of the compiler. It means using a compiler that is nomore aware of all the aspects of the code it is handling. Errors will appear only in a later stage and thus become difficult to put back in the source code context.

o Mixing java code annotation and XML descriptors (automatically generated and/or manually writen) will produce complexe and difficult to maintain systems. The configuration data will be spread over even more technologies; in France we call this the GAS-PLANT syndrom. Documentating becomes very difficult and your development team will need mixed expertises and require a multi semantic perception process in order to capture the whole picture of a project .

o Abusing annotation is easy because it is an open window to an infinit way of extending JAVA and when something is easy and sexy it become popular ;-). Abuse will also be driven by sophisticated tools like IDE wizards. Such tools will promote powerfull extension of JAVA but the resulting generated and annotated code will be difficult to understand and maintain by humans.

There are many more reasons java annotations can be harmful however I think Robin's extremly well writen and pertinent comments should be more then enough to make people at least careful when using them.

I am surprised by the number of negative reactions to Robin's post. In some (sad) way it means that the mermaid song has already charmed the JAVA travelers.

Thierry


Thierry thanser@noos.fr
Leeds, UK

Thu Nov 23 11:41:38 GMT 2006
You know what I'd like?
I wish that the java languagfe permitted the use of european single and double quotes to delimit generic parameters and annotations (respectively).

I just think it would look cool.

Oh - and there's no reason whatever why a unicode Pi could not have been included in java.lang.Math as a synonym for PI . The greek unicode Pi counts as a valid java identifier.

Paul Murray pmurray@bigpond.com
Canberra, Australia

Tue Jan 16 03:06:57 GMT 2007
hmm, there's some interesting points here, it's worth thinking about, right? the thing that surprises me is that a lot of people are so sure, one way or the other...
imo:

1 - the thing about metadata vs decorator seems to be a tangential topic about terminology, though i'm probably missing the point

2 - fear/resistance to change. sure, i think this is always an effect, but i think obviously if you accept everything as a good thing without thinking it through, it leaves yourself (or your language/project/company) open to a lot of abuse. my mind isn't made up on annotations.

3 - i think comments from Thierry thanser@noos.fr really homes in on the the basis of my fears, albeit focussing on worst case side only. i think the point about good/bad programmers is pertinent here but, frankly, there are a lot of bad
programmers around and a more complicated language, more confusions and more possibility for going haywire might not be the best tools to give them...

4 - personally i guess i'm more suspicious of changes that seem to massive overlap with solutions implementable easily in standard java. obviously standard construct like @Override are providing something new and good, but are things like google-guice just the thin end of the bleed-from-java-to-annotations wedge (or does it just have a faintly nauseating
name)? obviously the google ppl as a rule aren't daft, so i'll be looking at this one with interest.

5 - i don't think comments about 'if you don't like it, ignore it' stand up in the real world - it's out there, people will use it for projects/libraries, so working programmers will have to use/maintain/extend code with annotations - the question is, on average, will it be a good/bad thing?

anyways, thanks for the article,
dan.

Dan Moore

Mon Mar 19 11:56:52 GMT 2007
so much bad gas
All these posts about "fearing change" are so much bad gas. Change can be for the better, or the worse. Annotations are for the worse. I will learn them, because some middle manager will require them, but I'm not convinced they've improved my productivity, or the maintainability of the code.

noj nojo@gmail.com
Canada

Mon Apr 02 02:33:16 BST 2007
they are meta data
Decorative data as you call it is a form of meta data. Metadata is information whose subject is other information. The fact that that other information is not intrinsic to the data (this is a class, this is a field) is not relevant. I can decide to annotate, that is add metadata, of any sort to information.
Anonymous person

Fri Nov 02 12:24:34 GMT 2007
Dispersed Semantics?
Today is the first time I've looked at annotations, so please excuse me if I have missed something, but it seems that the mechanisms for dealing with annotations at run time (i.e. via reflection) leaves a lot of scope for dispersing an applications'/librarys'/etc semantics throughout the respective software entities' code and potentially, in the case of a library, throughout the code of any other entities that may utilise it.

How can we find where an annotation's semantics are defined? Presumably any class or instance can use reflection to discover if some variable, Class, etc. has an annotation and do 'something' based on that information. If it were logging, testing or something orthogonal to the core logic of the application this is probably OK, otherwise, don't annotations leave a lot of room for obfuscating a semantics and intention? Of course, one could document the intended use of the annotation, but how would we know where to find this documentation? What if some other developer decides that the locations at which an annotation is used are also places where some other logic is applicable and 're-uses' the annotation? How can we determine that this has occurred?

I guess reflection could be abused like this in general, but abuse does not seem so common. I wonder if the perception of annotations as meta-data (or decorative data... or whatever) which is 'separate' to the operation of the class will lead to different practices?

Having said that, I think annotations would be great when used wisely in frameworks... I got so sick of implementing ParameterAware and friends in Struts2 that I now reference everything via a static context, which presents its own issues in terms of clearly identifying semantics and intentions.

Simon
Canberra, Australia

Sat Nov 17 09:29:35 GMT 2007
Code Maintenance
My concern with some of the Java 5 features such as annotations and generics is that they make it very easy to write unreadable code.

I'm not suggesting that the features are not useful, but the tradeoff for the elegance they offer is an increase in complexity.

Obviously you can write unreadable code without these new constructs. But suggesting "If you don't like the new features, don't use them" overlooks the fact that a lot of us spend about 80% of our time maintaining other people's code.

I believe that Java's simplicity has been a major strength, not a weakness.

My gusess is that the new features will be overused/misused and that in the long run they will cost more than they gain.

demi

Sat Feb 09 17:07:37 GMT 2008
More freedom more fun
Annotations give you additional freedom to implement your ideas. It's up to you to decide whether to use new features of java or not. If you don't know how and when to use new concepts, it does not mean that those features are redundant. Annotations give you additional dimension. More freedom you have - more fun you gain from development, more flexible your code becomes.

You dont want annotations. I do.

Alexander
Russsia

Sat Mar 08 12:53:34 GMT 2008

Post a new message

 

Related Articles

Improve Your Interface Designs

Code Generators - The Fastest Way to Write Software?


<< Back to Programming

All trademarks and copyrights on this page are owned by their respective owners.
Stories and articles are owned by the original author.
All the rest Copyright © 1998-2008 Matt Stephens. ALL RIGHTS RESERVED.