Archive for the ‘Software Development’ Category

The Myth of “One Place to Change”

According to the discipline and punish link blog entry:

Except putting schema code all over the place tends to be a recipe for spaghetti. The benefit of Repository classes is there’s only one place in the code that has to change when your database schema changes.

Yeah, right. Based on my experience, when the database changes, it is because you need to track some new piece of information, and that inevitably ripples through every layer, all the way to the GUI screen where you now need something like a new text field to enter the data.

Nice theory, but I don’t think you see that kind of utopia all that often.

Next Week’s Assignment

Today is Saturday, at least here in the USA it is. (I think it’s Thursday south of the equator, right?) At any rate, here is your homework for Monday when you return to “work”:

Find the longest human-coded class in a Java application at your company. Also, find the longest human-coded method in a Java application. Post the results here.

This is Thanksgiving week here in the USA, so it’s not like any of you are actually working next week. This should be fun!

Great Blog

For “longest”, let’s just count the number of “\n” characters.

Bonus points to anyone who knows of a simple program that can produce these metrics by quickly scanning an entire directory tree. Counting lines of code in a class is easy with a bit of shell scripting mojo, I’m not so sure about counting lines of code in individual methods.

I suppose you might try to briefly explain the reason these classes and methods are so abnormally huge, without exposing anything proprietary. We wouldn’t want to embarrass anyone, after all.

Bug Tracking: How Do You Do It?

This quote from OpenJDK Infrastructure Roadmap resonates with me:

…they had considered something like that but that the blocker was the lack of a mechanism to have a fix target multiple releases.

Suppose you have trunk, 1.9, 1.10, and 1.11 branches. Customers use the software at all of those release levels (except for the trunk, of course), and critical bug fixes are often ported to numerous different branches. Most defect tracking tools do not support this, or do so poorly.

Speaking in general terms, a “classic” bug tracking tool has a core record with a name like “Issue” “Change Request” or “Defect”. Whatever you call it, the concept is generally the same. The Issue probably has attributes such as status (new|in progress|fixed|verified fixed), priority, responsibility, synopsis, and several other attributes.

The workflow might go like this:

  1. Someone reports a bug.
  2. You create an Issue, setting the Reported Against attribute to 1.10, since that is the version the customer uses.
  3. A programmer fixes the problem, marking the Issue “fixed”.
  4. The Issue goes to QA for testing, etc…

I already have questions about this workflow:

  • In which branch did the programmer commit the fix? 1.11? trunk?
  • Once the Issue is marked “fixed” (assuming in trunk), how do we backport to other branches?

If a customer on release 1.9 calls up and reports the same problem, can you easily do a query and say “Yep, looks like that is fixed in version 1.12″ ?

Do you create new Issues for each and every branch you apply the fix to? That seems wasteful. But the original Issue is already marked Fixed.

One Idea

Perhaps the original Issue report shouldn’t have a Status at all? Maybe, instead, each Issue has a list of one or more “Work Request” records? Each Work Request belongs to a particular software release level, and each Work Request has its own status.

One issue might have three Work Requests: trunk, 1.10, and 1.11. You can then do a query to determine the issue is Fixed in trunk and 1.11, but not yet backported to 1.10.

How Do You Do It?

I’m very interested in learning how other companies handle this. Do any defect tracking tools support status tracking for multiple software branches, or do people just make copies of defect reports for each and every branch?

Easy 2 Test == Less Reason to Test ?

Some classes are incredibly easy to test:

public class Name {
  private final String first;
  private final String last;

  public Name(String first, String last) {
    this.first = first;
    this.last = last;
  }

  public String getFirst() { return first; }
  public String getLast() { return last; }
}

Should we write unit tests for these simple classes? Kevin “pottymouth” Bourrillion brings this up as well:

If we write tests for these idiotic classes, we’re wasting time; if we don’t write tests for these idiotic classes, we find out later that they’re buggy because, say, we forgot to use a null-safe equality check for a nullable field, or something.

So what do you do? Do you test trivial code?

The Testing Suite Spot

Let’s look at an advanced diagram showing code complexity:

Testing Chart

Some code feels too trivial to test, so we don’t test all of those getters and setters. Other code is awful legacy crap that is damn near impossible to test. The tests become so convoluted, time-consuming, and hacky that we don’t bother.

Random Observations

  • If you wait until code gets really complex before writing that first test, it is generally too late. It is damn hard to retrofit existing code with good tests.
  • Most code starts out pretty simple. You may feel like you are wasting time testing this trivial code, but complexity sneaks up on you.
  • Writing that first stupid trivial test helps ensure you lay a foundation for ongoing testing. Are your build scripts up-to-snuff? Does you continuous integration build run the tests? Do you publish test results? Putting these features in place on day 1 is easy, when the code is “too trivial to test”. Procrastination makes all of these things much harder.
  • Testing as you go helps avoid complexity in the first place. People who never write tests do not grasp this concept.

I believe the last bullet is the most important. Code that is “too hard to test” is often that way because you did not write tests as the code evolved rotted.

Should We Test Trivial Code?

Back to the original question. Should we write tests for trivial code? I don’t see much harm in writing a handful of trivial tests for each class. I see far more harm in writing too few tests. Even if classes never evolve beyond simple POJOs with a few getters and setters, writing trivial tests wastes very little time. If the code happens to grow and require new features, having those first few tests gives you a better starting point.

As a learning exercise, writing tests for trivial classes is the first step towards understanding how to write tests for the really hard stuff. The stuff that really needs testing.

I Hate RSS

I am in the midst of writing a newsreader client that must display content from both RSS and Atom feeds. I am using ROME to parse the feeds, which I then display in my GUI. ROME handles a vast majority of parsing nastiness, I just have to interpret and display whatever ROME gives back to me. Rome provides the least-common-denominator of every possible feed, which leaves a lot of room for ambiguity.

Today I discovered that for some RSS feeds, ROME tells me the content type is “text/plain”. When I dutifully attempt rendering as text/plain, I find the feeds in fact contain HTML markup like hyperlinks. When I test these exact same feeds in tools like Google Reader, I see that they treat them as HTML instead of plain text.

Other RSS feeds report their content type (again, via ROME) as text/html.

I do not know a good way to handle this. I guess I’ll just blindly assume that every RSS feed contains HTML, regardless of what the content type says.

This sucks. If you ever have the opportunity to PRODUCE your own feed, PLEASE consider using Atom. And if your feed contains HTML tags, why on earth would your feed tell everyone it is text/plain?

For a Great Time, Try These IDEA Project Tips

Most of these are IDEA specific, but a few concepts in here translate well to other IDEs, I suppose. A basic IntelliJ IDEA project consists of three files:

  • myproj.ipr - this is the project file
  • myproj.iml - a module file, you might have a bunch of these
  • myproj.iws - a workspace file

Here are a handful of tips for managing these files.

New IDEA, New Format

People generally store their IDEA project and module files in the root directory of their project. Take a look at the Guice trunk directory. See the .iml and .ipr files?

As IDEA evolves from release to release, the project file format changes. So if you use the exact same version of IDEA as the Guice authors, you can use their project file. But if you happen to use an older version of IDEA, you probably won’t be able to use their project file. Or, if you open the files with a new (or beta) version of IDEA, the file might get upgraded to the new format.

I always store my project and module files in version-specific directories:

trunk
 |
 +--idea5
 |      .iml, .ipr files for IDEA 5
 +--idea6
 |      .iml, .ipr files for IDEA 6
 +--idea7
        .iml, .ipr files for IDEA 7

Easy, right? This lets different programmers collaborate on the same project without trampling each other’s project and module files.

Relative Paths

IDEA uses relative or absolute paths in both the project file and the module file(s). Modules default to relative paths, the project file defaults to absolute paths.

If you plan to share your project and module files, be sure to set BOTH the project AND module settings to relative paths. This is particularly critical in the directory structure shown above, because all of the paths need to include “../” due to the idea5, idea6, or idea7 directories.

Relative paths are important because different programmers use different directory structures on their computers. Furthermore, if you use Subversion (or other version control tools), your branches will be checked out to different directories. Having all relative paths in your IDEA project and module files means you can do a fresh checkout to any path and get to work right away.

CRLF Woes

I work on a team where some programmers use Linux, others use Windows. We found if a Linux user changes the project or module in any way, IDEA stores using “\n” line endings. If a Windows user modifies the files, IDEA stores the files using “\r\n”. Sigh. I wish IDEA would just store “\n” always.

To avoid this problem, configure your version control tool (CVS, Subversion, whatever) to always store these files using a particular line ending style. In Subversion, you simply set an attribute called

svn:eol-style

on these files. This avoids bogus diffs if your teammates use different operating systems.

Do Not Share *.iws

The .iws file is a workspace file. This contains programmer-specific preferences. Do not share this with other programmers, and DO NOT check this in to a version control repository. If you do, every programmer who opens the file in IDEA will modify it, and you’ll constantly be updating, merging, and resolving conflicts.

If the .iws file is not found, IDEA silently creates a new one for you, so there is no reason to share .iws files.

Avoid Ant Conflicts

I always configure my Ant buildfiles to produce output in a “build” directory. I configure IDEA to put its output in a different directory. It seems to cause problems when two different build systems compete for the same directory.

Ignores

Be sure to tell IDEA to exclude directories that are unrelated to compilation or runtime settings. If your Ant buildfile drops .class files in a directory independent of IDEA’s build directory, be sure to configure your module to exclude the Ant output directory. Otherwise every time you compile in Ant, IDEA will re-scan all of those Ant build artifacts. You should also exclude things like documentation directories, again for performance reasons.

Source Paths

Put your source code in a ’src’ directory of some sort. Configure that as a source path in IDEA. I’ve seen many programmers list OTHER directories as “source” directories as well. I don’t know why so many people do this, but it is not a good idea. For example, we generally have a resources directory that contains images and properties files that should be added to the CLASSPATH at runtime. The resources directory SHOULD be added to the CLASSPATH, but it SHOULD NOT be added as a “source” directory.

Adding non-source code as a source directory slows things down as IDEA scans those files, copies them to cache folders, etc.

I generally like several parallel source paths. I’ll have at least one for application code, and another for unit test sources. I like keeping XML, .properties, and image files in a separate resources folder.

Many people like to put these collateral files right in there with application source code, which I believe is a mistake. They must then add a source directory to the CLASSPATH (which is weird), or they must rely on Maven or Ant to COPY these collateral files to a build directory during the application build. Yuk, yuk, yuk! Having to copy these files around just leads to problems that are completely avoidable.

Be Careful with Plugins

Unfortunately, some plugins store programmer-specific settings in the .ipr file instead of the .iws file. This means if one programmer installs some plugin and commits the project file to the version control repository, other programmers on the team now see what are essentially bogus diffs (and potential conflicts) in the files.

I simply stopped using one plugin because of this behavior. Just something to look out for.

Gosling + Silverlight = I’m Confused

When James Gosling mentions Silverlight on his blog, is he talking about Microsoft’s Silverlight (as in a big competitor for Flash, JavaFX, etc), or something else called Silverlight?

By the way, ZFS sounds really awesome.

BPM: Not Even Comic-Worthy

I don’t really think this is all that funny, but describing how I could conceivably make a comic strip might clarify my opinion on John Reynold’s recent blog entry: Why Do Java Developers Hate BPM?

In this blog entry, John rehashes some really, really, really old arguments:

BPM suites make programming boring. They force you to use point-and-click and drag-and-drop tools to design your process diagrams, data models and forms. What’s worse, they actually encourage Business People to model processes and design forms on their own.

And…

BPM suites are a threat to traditional Java programmers. These suites are far from perfect, but even in their current state we can see where things are heading. The days of the Java Guru as indispensable are fading.

Just substitute the word “CASE” instead of “BPM”. Or “UML”, or “4GL”, or “MDA”. They all fit the same template argument. (maybe we could turn this into some kind of Mad Libs exercise?)

The Comic Idea

Here’s how the comic strip would look…

Frame 1 - 1981

A picture of a guy (presumably James Martin, the author) holding up his 1981 book: Application Development without Programmers. He’d be saying something along the lines of “pretty soon CASE tools will make programmers irrelevant”.

Frame 2 - 1990s

Someone hawking some UML tool or 4GL. Again, claiming “pretty soon programmers won’t be needed.”.

Frame 3 - 2000s

A guy promoting OMG Model Driven Architecture. You can guess the claim.

Frame 4 - Now

You guessed it, BPM. The same old drivel about “point and click / drag and drop” application design.

I won’t make this comic, though. Not funny. Been there, done that.

I Cannot Say It Better Than…

Check out this quote from a 2005 Computerworld blog entry:

By the time technology has advanced far enough to create a really great tool for automagically producing a broad class of applications, it also has advanced far enough to support other kinds of application functionality that the tools don’t support (except possibly through major coding).

Trust me, your job as a highly talented computer programmer is quite secure.

Programmer’s Notebook: Uncaught Exception Handlers

Summary: learn how to use Thread.UncaughtExceptionHandler effectively in rich client (a.k.a. Swing) applications.

UPDATE: See One More Note on Uncaught Exception Handlers for important information about exceptions thrown from modal dialogs.

Quick Review

Java 5 introduced a new way to catch unexpected exceptions: Thread.UncaughtExceptionHandler. This is an interface with the following API:

public interface UncaughtExceptionHandler {
  void uncaughtException(Thread t, Throwable e);
}

Your job is to write a class that implements this interface. You then register your implementation on a per-thread basis, or globally for every thread. To register your handler for a single thread you do something like this:

Thread.currentThread().setUncaughtExceptionHandler(new MyExceptionHandler());

To register your handler for every thread, do this:

Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());

Notice that setDefaultUncaughtExceptionHandler(...) is a static method in the Thread class, while setUncaughtExceptionHandler(...) is a non-static method.

A Sample Swing App

Here is a very simple Swing application that shows two buttons:

Demonstration App

If you click the “EDT Exception” button, it throws an exception on the event dispatch thread (EDT). If you click the “Thread Exception” button, it starts a background thread that throws an exception.

In both cases, a stack trace appears on the console. But the EDT exception messes up repainting, so the button does not paint properly until you move your mouse around a bit. Fortunately, Swing recovers and the app continues. Here is the complete source code:

public class Main extends JFrame {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Main().setVisible(true);
            }
        });
    }

    // throws an exception on the event dispatch thread
    private Action edtAction = new AbstractAction("EDT Exception") {
        public void actionPerformed(ActionEvent e) {
            throw new RuntimeException("Exception generated on the EDT");
        }
    };

    // throws an exception on another thread
    private Action threadAction = new AbstractAction("Thread Exception") {
        public void actionPerformed(ActionEvent e) {
            new Thread("Sample Thread") {
                public void run() {
                    throw new RuntimeException("Exception thrown on a thread");
                }
            }.start();
        }
    };

    public Main() {
        super("Uncaught Exception Handler Demo");

        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        buttonPanel.add(new JButton(edtAction));
        buttonPanel.add(new JButton(threadAction));
        getContentPane().add(buttonPanel, BorderLayout.SOUTH);

        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Simple enough. Let’s add an uncaught exception handler.

MyExceptionHandler

Here is a simple uncaught exception handler that shows the exception message in a dialog box.

public class MyExceptionHandler implements Thread.UncaughtExceptionHandler {

    public void uncaughtException(final Thread t, final Throwable e) {
        if (SwingUtilities.isEventDispatchThread()) {
            showException(t, e);
        } else {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    showException(t, e);
                }
            });
        }
    }

    private void showException(Thread t, Throwable e) {
        String msg = String.format("Unexpected problem on thread %s: %s",
                t.getName(), e.getMessage());

        logException(t, e);

        // note: in a real app, you should locate the currently focused frame
        // or dialog and use it as the parent. In this example, I'm just passing
        // a null owner, which means this dialog may get buried behind
        // some other screen.
        JOptionPane.showMessageDialog(null, msg);
    }

    private void logException(Thread t, Throwable e) {
        // todo: start a thread that sends an email, or write to a log file, or
        // send a JMS message...whatever
    }
}

To use this handler, you must register it. Simply modify the code as follows:

public static void main(String[] args) {
    Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());

    ...

Now, whenever an “unexpected” exception occurs, MyExceptionHandler kicks in and shows this lovely dialog box:

Unexpected System Problem

As an added bonus, the GUI repaints properly when this dialog displays.

This is Not Production Quality!

This is not a production-quality example! Let’s run down a list of features you will need to consider in a “real” application.

  • Event Dispatch Thread (EDT) confinement. As our UncaughtExceptionHandler shows, your uncaughtException method must ensure it is on the EDT before showing an error dialog or interacting with other Swing GUI components.
  • Dialog ownership. If you use a dialog box, your app will need to use a proper owner Window. My example simply passes null as the owner, which is unacceptable in a real app. Failure to specify an owning window causes dialog boxes to get buried, which (as we found) causes many users to simply reboot their computers. Yes, the typical computer user does not know how to Alt-Tab through Windows, nor do they know how to use task manager to kill a process. Make sure you never bury a modal dialog!
  • Consider a non-modal dialog. Many modern apps show unexpected problems in a flashing indicator in the status bar.
  • If you use a modal dialog, include an exit button. Sometimes when you hit OK, the exception occurs again, which triggers a new dialog. If modal, users are locked in and really need an exit button to abort the app.
  • If you report errors back to “home base” via email or some other mechanism, do not do it on the event dispatch thread. Spawn a background thread.
  • Make damn sure your unexpected exception hander includes try/catch blocks so you NEVER trigger yet another exception. If you do, you can get caught in infinite recursion as you display more and more errors.
  • If your dialog is already visible, do not create another one. Consider the case when a table cell renderer throws an exception. Your dialog displays, which triggers a repaint event, which causes another exception, etc. If your dialog is already visible, ignore the next exception. Otherwise you’ll get caught in an infinite loop.
  • If you are really sneaky, you can use Robot.createScreenCapture() to capture a picture of your app. Be very, very careful about privacy concerns. This is only acceptable in an internal corporate environment…even then, there are significant ethical considerations. :-)
  • Consider the possibility of an unexpected exception before your main window appears. If your window is not even visible yet and you try to create a modal dialog using that window as its parent, your dialog won’t appear.
  • If your customers are not comfortable with automated error reporting, consider adding a button that lets them choose to optionally send an email along with a screen shot.
  • See also One More Note on Uncaught Exception Handlers for important information about exceptions thrown from modal dialogs.

As you can see, there are many details to consider. Real apps are just so darn messy…

Sling Blade Runner

Check out this puzzle from ITA Software. (if that link ever goes bad, here is their puzzle archive).

“How long a chain of overlapping movie titles, like Sling Blade Runner, can you find?”

Use the following listing of movie titles: MOVIES.LST. Multi-word overlaps, as in “License to Kill a Mockingbird,” are allowed. The same title may not be used more than once in a solution. Heuristic solutions that may not always produce the greatest number of titles will be accepted: seek a reasonable tradeoff of efficiency and optimality.

I started tinkering with this last week and spent several evenings working on a solution. My first attempt was a brute force algorithm that tried every possible combination.

After letting my program run 24 hours, it was still processing the third movie…out of a list of 6561 movies! Clearly brute force is not the way to go.

Building the Data Structure

My current algorithm works as follows:

  1. Load the file into memory
  2. For each movie title, create a Movie object
  3. Each Movie has a list of “prefixes” and “suffixes”. For example, prefixes for “TO KILL A MOCKINGBIRD” are “TO”, “TO KILL”, and “TO KILL A”. I put all prefixes and suffixes into hash maps. Furthermore, I have a cross reference Map that uses an integer as a key that maps to String prefix and suffix values.
  4. I then create a graph, linking every matching prefix and suffix together, using the integers from my lookup table. Thus, each Movie object now has a Set of every possible predecessor and successor movies.
  5. Prune all movies that have no predecessors or successors. This eliminates 2092 movies right away.
  6. Walk the graph…more on this in a bit

Reading the data file, building the graph, and pruning the unwanted movies takes less than a second. Walking the graph is where it gets interesting.

Walking the Graph

Do this for each movie:

  1. The first movie is the starting point. Its distance is 0.
  2. Find all predecessors. Their distance is 1.
  3. Recursively continue, incrementing the count by 1 each time.

It’s a wee bit more complicated than that, but not much. For each “starting movie”, I create a new linked list. Each node in the list contains the distance from the starting point, a reference to the current movie, a reference to the starting point, and a link to the predecessor node in the linked list.

By keeping these linked list nodes (along with an extra Map in each Movie), I can avoid hitting the same movie more than once per starting point.

Lessons Learned

The graph contains *many* cycles. Thus, depending on the order in which you traverse the predecessors, you get different counts. On average, I find chains around 200 movie titles long. This takes around 15 seconds on my computer. I just randomly shuffle the children and keep re-running the app, hoping to find a longer chain.

I only have a single CPU machine. My algorithm is memory intensive due to all of the linked lists, but that’s no problem for several thousand movies. If I had more CPUs, I could very easily make it threaded to (hopefully) improve performance. For millions of titles, you’d have to come up with a different approach I’m sure.

It turns out that pruning those 2092 movies hardly matters in terms of runtime performance. That was a big surprise.

Just for Fun

I didn’t do this to apply for a job at ITA. It just looked like a good challenge. It turned out to be a bit harder than I first anticipated. I really don’t have any ideas for reliably finding the “longest” chains.

The Longest Chain

Here is my best chain so far.

1. MRS PARKER AND THE VICIOUS CIRCLE
2. CIRCLE OF FRIENDS
3. FRIENDS WITH MONEY
4. MONEY FOR NOTHING
5. NOTHING BUT TROUBLE
6. TROUBLE IN PARADISE
7. PARADISE ROAD
8. ROAD GAMES
9. GAMES PEOPLE PLAY NEW YORK
10. NEW YORK NEW YORK
11. NEW YORK COP
12. COP LAND
13. LAND OF THE DEAD
14. DEAD MAN
15. MAN ON FIRE
16. FIRE IN THE SKY
17. SKY HIGH
18. HIGH SPIRITS
19. SPIRITS OF THE DEAD
20. THE DEAD GIRL
21. GIRL IN THE CADILLAC
22. CADILLAC MAN
23. MAN OF THE HOUSE
24. THE HOUSE OF THE DEAD
25. DEAD BANG
26. BANG BANG YOURE DEAD
27. DEAD MAN WALKING
28. WALKING AND TALKING
29. TALKING ABOUT SEX
30. SEX AND THE OTHER MAN
31. MAN TROUBLE
32. TROUBLE EVERY DAY
33. DAY OF THE WOMAN
34. THE WOMAN IN RED
35. RED HEAT
36. HEAT AND DUST
37. DUST TO GLORY
38. GLORY ROAD
39. ROAD HOUSE
40. HOUSE PARTY
41. PARTY MONSTER
42. MONSTER IN A BOX
43. BOX OF MOON LIGHT
44. LIGHT OF DAY
45. DAY FOR NIGHT
46. NIGHT OF THE LIVING DEAD
47. DEAD OF NIGHT
48. NIGHT MOTHER
49. MOTHER JUGS AND SPEED
50. SPEED 2 CRUISE CONTROL
51. CONTROL ROOM
52. ROOM AT THE TOP
53. TOP GUN
54. GUN CRAZY
55. CRAZY AS HELL
56. HELL NIGHT
57. NIGHT AND THE CITY
58. CITY BY THE SEA
59. SEA OF LOVE
60. LOVE AND DEATH
61. DEATH WISH V THE FACE OF DEATH
62. DEATH BECOMES HER
63. HER MAJESTY MRS BROWN
64. BROWN SUGAR
65. SUGAR AND SPICE
66. SPICE WORLD
67. WORLD TRADE CENTER
68. CENTER STAGE
69. STAGE FRIGHT
70. FRIGHT NIGHT
71. NIGHT AND DAY
72. DAY OF THE DEAD
73. DEAD END
74. END OF DAYS
75. DAYS OF HEAVEN
76. HEAVEN CAN WAIT
77. WAIT UNTIL DARK
78. DARK CITY
79. CITY OF JOY
80. JOY RIDE
81. RIDE THE HIGH COUNTRY
82. COUNTRY LIFE
83. LIFE AS A HOUSE
84. HOUSE OF FRANKENSTEIN
85. FRANKENSTEIN AND THE MONSTER FROM HELL
86. HELL UP IN HARLEM
87. HARLEM RIVER DRIVE
88. DRIVE ME CRAZY
89. CRAZY PEOPLE
90. PEOPLE WILL TALK
91. TALK OF ANGELS
92. ANGELS WITH DIRTY FACES
93. FACES OF DEATH 4
94. 4 LITTLE GIRLS
95. GIRLS OF SUMMER
96. SUMMER CATCH
97. CATCH A FIRE
98. FIRE ON THE MOUNTAIN
99. THE MOUNTAIN MEN
100. MEN WITH GUNS
101. GUNS OF THE MAGNIFICENT SEVEN
102. THE MAGNIFICENT SEVEN RIDE
103. RIDE WITH THE DEVIL
104. THE DEVIL RIDES OUT
105. OUT OF THE PAST
106. PAST MIDNIGHT
107. MIDNIGHT RUN
108. RUN SILENT RUN DEEP
109. DEEP BLUE
110. BLUE CAR
111. CAR 54 WHERE ARE YOU
112. YOU LIGHT UP MY LIFE
113. LIFE WITH FATHER
114. FATHER OF THE BRIDE
115. BRIDE OF THE WIND
116. THE WIND AND THE LION
117. THE LION KING
118. KING OF THE JUNGLE
119. JUNGLE 2 JUNGLE
120. JUNGLE BOOK
121. BOOK OF LIFE
122. LIFE IS BEAUTIFUL
123. BEAUTIFUL GIRLS
124. GIRLS WILL BE GIRLS
125. GIRLS GIRLS GIRLS
126. GIRLS JUST WANT TO HAVE FUN
127. FUN AND FANCY FREE
128. FREE WILLY 2 THE ADVENTURE HOME
129. HOME ALONE 3
130. 3 NINJAS KICK BACK
131. BACK TO SCHOOL
132. SCHOOL OF ROCK
133. ROCK STAR
134. STAR TREK IV THE VOYAGE HOME
135. HOME ALONE
136. ALONE IN THE DARK
137. DARK STAR
138. STAR TREK THE MOTION PICTURE
139. PICTURE BRIDE
140. BRIDE OF THE MONSTER
141. MONSTER HOUSE
142. HOUSE PARTY 3
143. 3 NINJAS KNUCKLE UP
144. UP CLOSE AND PERSONAL
145. PERSONAL BEST
146. BEST OF THE BEST
147. THE BEST OF EVERYTHING
148. EVERYTHING RELATIVE
149. RELATIVE FEAR
150. FEAR X
151. X THE MAN WITH THE X RAY EYES
152. EYES OF AN ANGEL
153. ANGEL BABY
154. BABY SECRET OF THE LOST LEGEND
155. LEGEND OF THE LOST
156. THE LOST BOYS
157. BOYS LIFE
158. LIFE OR SOMETHING LIKE IT
159. IT TAKES TWO
160. TWO FRIENDS
161. FRIENDS AND LOVERS
162. LOVERS AND OTHER STRANGERS
163. STRANGERS WHEN WE MEET
164. MEET JOE BLACK
165. BLACK AND WHITE
166. WHITE HUNTER BLACK HEART
167. HEART CONDITION
168. CONDITION RED
169. RED EYE
170. EYE FOR AN EYE
171. AN EYE FOR AN EYE
172. EYE OF GOD
173. GOD TOLD ME TO
174. TO DIE FOR
175. FOR THE BOYS
176. BOYS ON THE SIDE
177. SIDE OUT
178. OUT COLD
179. COLD FEVER
180. FEVER PITCH
181. PITCH BLACK
182. BLACK HAWK DOWN
183. DOWN TO EARTH
184. EARTH GIRLS ARE EASY
185. EASY COME EASY GO
186. GO NOW
187. NOW YOU SEE HIM NOW YOU DONT
188. DONT GO IN THE HOUSE
189. HOUSE OF DRACULA
190. DRACULA DEAD AND LOVING IT
191. IT HAPPENED AT THE WORLDS FAIR
192. FAIR GAME
193. GAME OF DEATH
194. DEATH WISH
195. WISH UPON A STAR
196. A STAR IS BORN
197. BORN AMERICAN
198. AMERICAN ME
199. ME MYSELF I
200. I LOVE YOU TO DEATH
201. DEATH SHIP
202. SHIP OF FOOLS
203. FOOLS RUSH IN
204. IN PRAISE OF OLDER WOMEN
205. WOMEN IN LOVE
206. LOVE WALKED IN
207. IN COLD BLOOD
208. BLOOD DIAMOND
209. DIAMOND MEN
210. MEN CRY BULLETS
211. BULLETS OVER BROADWAY
212. BROADWAY DANNY ROSE
213. ROSE RED
214. RED RIVER
215. RIVER OF NO RETURN
216. RETURN TO HORROR HIGH
217. HIGH SCHOOL HIGH
218. HIGH CRIMES
219. CRIMES OF THE HEART
220. THE HEART OF ME
221. ME WITHOUT YOU
222. YOU ONLY LIVE ONCE
223. ONCE AROUND
224. AROUND THE BEND
225. BEND OF THE RIVER
226. THE RIVER WILD
227. WILD THINGS
228. THINGS TO COME
229. COME AND GET IT
230. IT HAPPENED ONE NIGHT
231. ONE NIGHT WITH THE KING
232. THE KING AND I
233. I WANT TO LIVE
234. LIVE FOREVER
235. FOREVER YOUNG
236. YOUNG SHERLOCK HOLMES
237. SHERLOCK HOLMES AND THE VOICE OF TERROR
238. TERROR BY NIGHT
239. NIGHT FALLS ON MANHATTAN
240. MANHATTAN MURDER MYSTERY
241. MYSTERY ALASKA
242. ALASKA SPIRIT OF THE WILD
243. THE WILD ONE
244. ONE EIGHT SEVEN
245. SEVEN YEARS IN TIBET