All project deliverables are due on the Sunday 5pm (end) of the deliverable week. private Piazza post of PDF is preferred. Please put words "210" and "deliverable" in the subject, as well as the name of the deliverable and your team name.
Software engineering not only embodies a set of key concepts and principles, it also entails a set of skills. Without proficiency in at least some of these skills, you cannot call yourself a software engineer. This course includes a project in order to help you get a taste of these skills as well as experience the key lessons of software engineering first-hand.
Few interesting programs can be built by a single person, so the project for this course is team-oriented. In addition to all the other skills and lessons that are to be conveyed, you will also be learning how to cooperate and communicate effectively.
In this project, you and your teammates will be defining a software product and seeing it through every stage of development. Because of the short span of this class, you are not expected to deliver a marketable product, but the result should be at least a compelling prototype that could serve as the basis for defining a real product or attracting venture capital. :)
You and your teammates have the flexibility--within certain parameters--to choose the product to develop and the features it provides. To provide some "spiritual" guidance, your product should attract the attention of the "Small World Venture Capital" investment fund, which specializes in promoting unusual products that promote a better world through strong communities. They have special interests in software that are targeted to a large group's needs. I will personally function as the Technical Liason of SWVC, and each team will be coming to me to seek guidance about what they can do to have a better chance of attracting additional funding. Each team has considerable autonomy, however, in defining its product and managing its team. For example, you are responsible for choosing a product that is within your means to develop within the alloted time. From time to time I may sense opportunities in the marketplace and suggest small changes to improve your market position. I will consider the possibility of teams developing competing products.
Consistent with the rest of this class, your project is to be conducted in a risk-centric fashion. Everything you do is about minimizing downside risks and maximizing return on up-side risk. Everything you turn in should be justified in terms of addressing a risk.
Here are some places to get inspiration (I can provide further details):
You really, really, really should have regular meetings; you should have a mailing list and chat set up, as well as a repository and issue tracker for all project information.
Communication is your biggest risk, since you probably have disparate schedules; this mutates into a coherence/consistency risk, amongst others. You've been warned! :)
Although each cycle focuses on resolving a certain class of risks, any previously unresolved risks should be monitored for realization or (preferably) elimination. Realization of unresolved risks requires a reprioritization.
For most cycles, there are six primary work products that must be incrementally refined and maintained:
If there were any money involved, there would also be a budget document. You may also want to keep supporting documents such as meeting notes and e-mails.
These work products are repeatedly augmented, refined, and changed. At no time is any document complete, unless the whole project is complete. It is impossible to know the future with certainty--and costly to try--so knowledge is acquired as its cost to acquire it drops below the rising cost of not having it.
Below are the deliverables that denote the major cycles of product development, as somewhat arbitrarily predetermined by me. Do not be misled by the titles on the deliverables. These are not the stages of a waterfall model that transform an input document to an output document. They are spirals that are focused on the resolution of a particular class of risks. The goal, then, it not production of documents, but resolution of risks and the successful production of a final product. The ``product'' is repeatedly (and incrementally) defined and evaluated at increasing levels of detail. You should augment these major cycles with minor cycles as-needed to resolve individual risks, etc.
Also, these deliverables are dates for you to deliver documents to me. It is expected that your actual work precedes the deliverables by quite a bit. My grading of these documents will constitute the ``review and commitment'' parts of the cycle (although normally this would happen in a highly interactive and probing meeting); you are responsible for validation, which is a much more detailed activity than the review for commitment. You should maintain your six work products on the web (accessible to me), and hand in the necessary portions of the products (with change marks, if necessary) for each deliverable.
A deliverable document must have the following form, although in some instances one element or another might not make sense for a given deliverable:
Although a deliverable is normally directed at addressing one class of risks, it potentially addresses all of your risks. What I mean is that, as a rule, a deliverable like the TTP is a "function" that takes in all your risks, and "returns" a new list of modified risks:
R' = M(R)
Or, more accurately, a deliverable takes the current-level product and risks, and refines them both:
(P',R') = M(P,R)
In other words, the Spiral Model is an technique that iteratively and incrementally eliminates (or at least lessens) risks, from big risks to small, from high-level to low level. In the early stages, P is just your deliverable documents and such, but soon it will be ethnographies, designs, code, etc. Conversely, your long list of risks will become progressively smaller, although it might never disappear (bad things can happen after release).
Sections 3, 4, 5, and 6 all concern the same risks. Section 3 is a high-level statement, something like I said about the TTP deliverable in the previous bullet (you can often lift this from my deliverable description). Section 4 lists your specific risks, not the categories (e.g., Failure to communicate quickly and precisely (because we have a large team with incompatible schedules)). Section 5 presents the resolution of each risk (e.g., we're going to use Slack, Google Docs, and meet twice a week). Section 6 discusses your resolution (e.g., together they provide instantaneous communication and a reliable project history and state; they're free and we already know how to use them, etc.)
Section 7 is an exhaustive list of risks that remain (R'). Note that the "plan for resolving them" is a plan on how you will solve them, not the plan that solved them. For example, schedule risk remains (despite adopting Agile development with frequent releases, etc.), and one thing that would help is a software design that enables parallel development. That's what you plan to do, but the software design is yet to come.
Some teams find this parallel structure constraining, because one technology choice will address many risks. For example, Agile addresses both communication risks with the customer (for a bunch of reasons) and delivery risks (specifically due to iterative/incremental development/releases). Having to discuss Agile twice is annoying. There are many ways to solve this problem. The easy way, in this section architecture, is to just mention Agile in section 5 under each relevant risk, and then in section 6 organize the discussion by the resolutions (Agile, Android, etc.) not the risks. So, in section 6, you would discuss Agile, noting along the way which resolutions it addresses (and creates, and how you do or plan to resolve them).
In other words, section 4 is a list of risks addressed, copied from the previous deliverable. Section 5 is, for each risk the list of resolutions for each risk. (Because of this highly parallel structure, you could combine 4 and 5.) Section 6 is organized into a list (or subections) of resolutions, discussing how each resolution resolves risks in section 5 (as well as what risks are added by the resolutions). Section 7 is what's left (and been added), and similar to 4, can be in a tabular form. The "plan" for Risks Remaining is not a risk resolution, but a process for resolving the risks. So your plan might simply be "we'll deal with this in the Testing Deliverable".
The purpose of the team participation report and attestation is to create transparency and accountability for every team member's contribution to a deliverable. It is not expected that every team member contribute the same amount to every deliverable, but rather, on average, over the entire project, that no team member is a free-rider. The document (a) reports each team member's fractional time spent on the deliverable, and (b) is signed by the entire project team. Your fractional effort is calculated as your hours spent on the deliverable, divided by the number of hours spent by the member of your team who spent the most hours on the deliverable. (I don't want to know how many hours were spent.) The fraction should be rounded to the nearest tenth. For example, if Bob, Sally, and Larry each spent 6, 7, and 8 hours on a deliverable, their fractional efforts would be 6/8=0.8, 7/8=0.9, and 8/8=1.0. I recommend that you use Adobe Acrobat's Sign & Certify feature to sign the report. In the event that the team cannot agree on the accounting of the participation, a minority dissenting report may be submitted. The majority report must contain a fraction for each team member, as decided by that majority. A minority report must contain the fractions of the dissenting members, plus any additional member fractions desired by the minority. The team effort report(s) must be submitted (together) as part of the PDF of the deliverable.
All deliverables are due the Sunday, 5pm, after the named week. You do not have to wait until the last day to complete the work for a deliverable. I recommend being about a week ahead, when possible.
If you receive a substandard grade on a deliverable, you can turn in a revision the following week for a regrade. Grades will be raised at most one full grade. The last two deliverables, Testing and Final Presentation, cannot be submitted for regrade, because they occur so late in the course. Revisions must be submitted in "redline", showing what you've changed, deleted, and added.
Redline is not hard to do, at least not in Word (instructions are for Window, Word 16):
Constitute a team with a size as specified in class. Submission this week is a list of team member names, student IDs, and e-mail addresses:
Name1
Your vision statement document should have the following, sectioned as
below:
If you want some guidance on vision statements, see Chapter 4, page 207
of Microsoft Secrets.
Important:You must have actual customers that you work with through
the entire project. Real stakeholders outside your team, the professor,
TA, etc.
Because we don't have a separate phase where risks are identified (and
new ones can be discovered at any time), it is important here to identify
your top risks for the project and product. Include not only customer
and competitor risks, but all major risks as you can anticipate them now.
Three categories of risks to never forget are team, technology, and time.
Finding all your risks is a creative activity requiring full team participation,
e.g., brainstorming.
Based on the issues (e.g., risks) identified in the previous
deliverable (or since), identify key tools, technologies, technical
skills, and processes that you will be depending on throughout
the rest of the project. Discuss the choices of your chosen tools,
technologies, and process, including the tradeoffs compared to things
you didn’t choose.
These tools, technologies, skills, and processes should be
complementary; they cannot be chosen only for their individual
strengths. Moreover, they must be well-suited to the constraints and
risks of the project (e.g., resolve the technology risks), such as
cost and time, size of the team, etc. Focus not only on what risks
technology resolves, but on the risks that the technology creates.
I cannot anticipate all the classes of tools you might need, but
your list and discussion should be comprehensive, from the tools of
development (e.g., IDEs) to the tools of deployment (e.g., client
and server technologies). Don't forget personal productivity tools
such as tools for creating and sharting documents and team communication.
The tools and technologies you choose may influence your low-level
software process (or vice versa). For example, use of
a modern IDE (integrated development environment) with a modern
code/document repository, etc., might enable an Agile software
process. This is why technologies and process are put together
in this deliverable. Process should not only include the traditional
aspects of a software process, but any kind of process you feel you
need to adopt to be successful.
NOTES (for this and future milestones): I expect you to be applying
Agile process as generally taught in the HFSD book. Yet I also
expect you to customize your process to your risks. Remember, the
Spiral Model teaches that you adapt your process to your risks, and
that you adaptively respond to the results of spirals (attempting
to resolve a risk).
Additionally, you must use GitHub and ZenHub for keeping track
of your code, stories, tasks, estimates thereof, as well as assigning
personnel. I'll be expecting you to maintain ZenHub/GitHub so
that it functions as a "big board" (i.e., you can see your project
status at a glance). You must use BDD-style stories and include the
BDD scenarios for each story. Just put the scenarios in the story
description. I'll expect you to use agile Velocity (i.e., efficiency)
in your estimation. Likewise I expect you to use Planning Poker
for estimation, or an equivalent technique. I want you to estimate
in days or hours, not Story Points. ZenHub only allows Story Points, but
you can just treat 1 point as 1 hour.) I'll want to see a Burndown
chart at the end of your two delivery Milestones.
Reminder: follow the specified form listed above the deliverables under
``A deliverable document should have the following form''.
Discover the actual needs of your customers. In essence,
you are starting with a problem from the customer's point of view and
elaborating that into a set of requirements for an improved or entirely
new system. This process is complicated by the fact that you have no
product to show your potential customers. But, ultimately, you are trying
to understand the customer's current work and pain points, which points
the way to requirements. Also, every potential
customer will have his or her own ideas, which may conflict with the
ideas of other. Moreover, your potential customers may (should!) have a
different background than you, complicating the communication process.
Do not lose track of the fact that you must not only satisfy the
customers of your product, but also those who are supporting your
project. You must capture current work practices in Scenarios
(full-length end-to-end ones, not BDD Scenarios), and perhaps Personas.
The requirements should be recorded in a way that they are
easily accessible and analyzable in future stages (e.g., Scenarios (true
storytelling), pictures). Again, Scenarios are required, Personas
are recommended. Even if not doing Personas, your Scenarios should
cover all the roles (unique kinds of stakeholders, e.g, if you were
doing a discussion board, posters, readers, and moderators). Your
methods should be documented. The requirements document you turn in
need not provide all the low-level data, however, only the results
and key supporting data. Some example low-level data is welcome.
You must use methods from the class in order to get full credit from
this assignment. That is, there must be an ethnographic component,
at a minimum Contextual Interviewing. It is not enough to do surveys
or regular interviews. Use of Scenarios to record the current work
practices (i.e., scenarios of success and scenarios of failure)
of your customers is required. You should analyze these scenarios
(and other data) to determine requirements.
Requirements analysis and risk resolution. Through
analysis and review of the collected requirements, identify conflicts,
problems, etc., attempting to resolve them before they consume your
project. Because you are still at an early stage, there are many
options open in terms of resolving problems, including changes to the
vision, product, customer base, marketing, management, etc.
NOTE: There is a big, but perhaps subtle, difference between
customer requirements and product design. The customer requirements
phase is about understanding the customer's problem,
their pain. The product design phase is about the solution
to the customer's problem. One problem can admit many solutions.
But if the customer requirements phase generates a solution, then
(a) you may not have understood the problem (and hence you may not be
solving it), and (b) you're not open to discovering other solutions.
Why might you want other solutions? They might be superior, they
might be cheaper, etc. In short, only do product design to the extent
that it helps clarify requirements (usually, this is no product design
at all.) Moreover, do not attempt to document your customer's
requirements with product design. Along these same lines, I'd recommend
against using User Stories or BDD Scenarios at this stage, as they
are optimized for describing features and product use cases, not
revealing or documenting requirements. Also, this is not the place or
time for Scenarios of Future Work, as this is product design.
In this deliverable, you define the product (at least for the
first milestone), and then plan the delivery of the first milestone (MVP).
Take the requirements from the previous week and design, define, and
record full-length, end-to-end scenarios (not BDD Scenarios),
and screens. Screens should be shown in progressions as part
of the scenarios. To manage repetition, you might want to use a
combined state machine of screens that comprise multiple scenarios.
Use of the word product is meant to emphasize the external
qualities of the software; that is, how a user interacts with and
perceives it, rather than its internal structure.
Next divide the features into two feasible milestones.
Enter your User stories and BDD Scenarios for the first milestone
into the project tracking system. User stories must be estimated,
divided into tasks (also estimated), and prioritized within the
milestone such that each completed user story results in a working,
testable, and usable system that can be demo'd to the customer.
Each story's tasks must also include a task for writing tests, and
a task for running and passing the tests (i.e., also debugging).
You can be writing automated unit tests or BDD-style story tests.
I recommend some of both. Finally, you should include a developer
Story or Iteration to allow time for testing against your relevant scenarios
of future success to ensure that the system works end-to-end and not
just the piecewise stories. These tests would be done by-hand, since
a lot of it is user experience.
You must use the BDD syntax (As an X, I Want Y, So That Z). Refine
the end-to-end scenarios into BDD scenarios for the user stories.
BDD scenarios are powerful because they not only define interactions
with the product, but serve as acceptance tests for the customer.
The level of detail required is enough for someone on your team to
implement the functionality. If more detail is required than detailed
above, it should be included.
Product design analysis and risk resolution. Although it is not
cost-effective to exhaustively analyze a system, certain critical
aspects of the system must be analyzed in order to ensure the
appropriate software gets implemented and that it will have certain
properties (such as liveness and fairness, as completely
arbitrary and potentially inappropriate examples). Using risk
analysis, identify these critical aspects and then analyze them for the
identified risks.
PROCESS NOTE: Some projects, based on their risks, may benefit
from a rapid prototype at this point. This might consist of a simple
GUI with a fake back-end, stylized use of a competitor's product,
by-hand emulation, prototyping of a "high risk" component, etc. If you
have "customer" risks (e.g., buy-in), or "requirements" risks, you'll
probably want to try out this prototype on your customers.
Deliver your Milestone 1 to your customer and solicit their feedback.
Conduct a postmortem for the milestone.
A major purpose of a milestone is to get feedback from users. We're
just getting feedback from our customers at this point, so it's more
like an interation or Sprint in that respect. Regardless, now's the
time for that feedback. Are these the features the customer really
wanted? How do they like the interactions you've designed? (You
should have gotten feedback from the screens earlier, but you can
get feedback on the final screens, too.) This should work a lot like
Contextual Interviewing, but you start with watching rather than with
interviewing. You move to interviewing if you have questions, and of
course at the end to get your questions answered. You might want to
have them "execute" one of the scenarios you solicited from them, although
now they are done in the new way, not the old way, of doing things.
A postmortem is an analysis of your project to determine success and
(primarily) failure factors: What you did, what you would do the same,
and what you would do differently next time? Quantitative,
qualitative, and totally subjective measures (e.g., intuition) should
be used. The focus is not on blame, but on improvement. Failure is
inevitable whenever an ambitious project is undertaken. Failing to
learn from it is not. It is recommended to use the description of
Microsoft postmortems in Microsoft Secrets as a template for
your own. A key element of a postmortem is restating the motivation and
objectives for the project: a project is first judged successful
relative to its initial objectives, although success is possible even
if the original objectives were not met if there is considerable
change in direction during the project.
A quality postmortem will benefit from good note-taking throughout the
process, although mailing list archives, document revisions, and your
issue-tracking system will be a gold mine. Plan for success of this
element.
Your postmortem need not be written as a lengthy narrative, although
precision and detail can be important. I recommend using a lot of
structure, with sections or headers and bullets.
Project replanning. You may have fallen behind schedule, learned
some important things from your customers, or discovered new
risks. Replan accordlingly. Discuss these changes as part of
this deliverable. Note that replanning may force you to cut out
inessential functionality or even redesign your product in order to
meet the deadlines and/or keep your customer happy.
The structure of a software product often has little to do it with defining
its function, but has everything to do with being able to implement,
test, and enhance the software at a reasonable cost, e.g., on schedule.
As a software system "ages", two things happen. One, clarity develops
on the system's function. This results in a better understanding of what
the software's design should have been (and should become). Two,
any modularity that originally existed has been eroded by frequent
changes and accretion of functionality, bringing the software's design
even further away from it's ideal structure.
Design a high-level architecture for your system, including
major components, connectors (including their type), and rules for
their composition. Review the product design and scenarios
derived from customer requirements to make sure that the macro-system
structure is well understood. Justify the appropriateness of the
architecture in terms of the risks it resolves.
To clarify the architecture's properties with respect to (incremental)
development, describe (perhaps via a developer scenario), at the
architectural level, how a a new feature is added to your application.
If your system does not adhere to this architecture, refactor it
accordingly.
Next, building on your software architecture, identify lack of SRP
/ information hiding that is particularly harming progress in your
project (see below), and refactor accordingly.
Refactor (redesign) your software with the following development
properties in mind (i.e., consider these as goals that address risks):
Together with your software architecture, the result is a design
specification. It may be desirable to also specify the behaviors
of the subcomponents, effectively ``dividing up'' your earlier
requirements specification to the components of the design.
The final design (and its rationale) should be documented at
a level of detail deemed appropriate by your method. Some sort of
architectural description with the interfaces of the major components
and their relationships is expected. As always, a risk assessment is
in order: May one module be much harder to build than the others?
May a key design decision by widely distributed? What if a key
component is not delivered on time? Appropriate courses of action
should be planned.
Your design methods, principles, and rationale should be documented.
NOTE: Please hand in your design as an architecture-and-design
document, as their tight coupling would make a design-only document
impossible, or at least hard, to understand.
NOTE: Your architecture cannot simply be model-view-controller. First,
MVC is a pattern. It becomes an architecture by (a) applying to the
entire system, and (b) becoming a ``rule of law'' about how the system
will be architected, not just a technique to be applied where convenient.
So, if your team finds itself moving towards MVC, it must be elevated to
the level of architecture. Also, the components must be instantiated
into their specific instances of model, view, and controller.
Additionally, if your system is any kind of cloud or client-server
type system, there are three architectural aspects that must be
addressed: the architecture of the client, server, and the means by
which the two are connected.
NOTE 2: An architecture is abstract - not fully represented
in your code. This was implied above when I asked you to design an
architecture for your system and then refactor your code (to make it
less abstract, i.e., to make the code better represent the architecture).
More to the point, architecture is a way of thinking about the
structure of your code - a constructed, abstract view. That means
your components aren't necessarily classes and your connectors
aren't necessarily method calls. A component may not be a single
class named after the component, but rather realized by a set of
collaborating classes. So you conceptualize the set of collaborating
classes as a component, but there is no such component in the code.
Design Patterns does have a pattern (at least one) for making
a component concrete, the facade pattern. But you don't need to
do that. Likewise, you might merely conceptually think of a certain
method call as an event or callback. Most languages don't really give
you a way to create new control abstractions (e.g., a way to make
an event connector from method calls). That's alright: abstractly,
you think of the method call as an event. And you can (should)
write about it that way in your architectural write-up. Finally,
architectural constraints are almost always abstract. There are
clever ways to check architectural constraints, but it is rare that
there is broad enforcement. Our languages just aren't rich enough.
However, you might have real connector objects and real components
in your system; they aren't always abstract. For example, in a
pipe-and-filter system, you might have real pipe connector objects
that pass data from filter to filter:
Milestone 2 Planning. Following the directions from Week 5
(please review), complete the planning for Milestone 2.
Up to now, you've probably been pretty lax about testing. That's
not the Agile Way, but doing the least work for the greatest short-term
benefit is. And so you probably cut corners on testing. As we
move towards final delivery, it's time to put together a more formal
plan to make sure the software will behave well in deployment, beyond
the simple demos that you've been delivering to the customer. To be
clear, this week's deliverable is not the performance of testing, but the
delivery of an end-to-end testing plan.
In many Agile methodologies, test cases are written first as a way
of defining the project and driving the development process (risks:
product ambiguity and knowing when you are done with a feature).
Here, we are actually interested in validating the correctness and
integrity of the final software product (risks: does it work and is
it ready to ship?).
Testing should occur at the earliest possible time to expose problems
before they are propagated. Already, requirements analysis, and design
reviews have taken place to ensure the integrity of the conceptual
aspects of the product. Moreover, you have designed your system to
allow it to be tested incrementally. Testing continues throughout
implementation, including:
Usability testing and aspects of system testing require the cooperation
of your customer, as it is the customer who decides whether the product
is what they want and is of sufficient quality.
At a minimum you should employ a functional testing approach, and take
steps to ensure completeness of the testing, although as always, your
testing should be risk-directed (both in what you test, how much, and how
it is tested). Minimality is not essential. As usual, your methods
and results should be appropriately documented (in what is often called
a testing plan).
By the end of this week, the testing infrastructure should be in
place, and testing as appropriate to the progress in the project
should be taking place.
Strict tracking of progress should be performed to identify problems
as early as possible. Note that development and related activities
should have been happening for several weeks.
Install the product, train your users, and pray. If you've done
everything else right up to this point, problems should be minimal.
However, at this point additional stakeholders (i.e., users) might
now encounter the system and have a different response than your
customer, who is a mere proxy user. A brief verbal report may be
requested in class.
If you haven't already, you should read ahead to next week's deliverable,
as there are things you should do this week, not next, particularly if
the final session is scheduled early in the week. Notably, you should
be getting feedback from your users, as outlined for the MS 1 deliverable.
Prepare a demo for the manager and the venture capitalists. The success
of this demo and the frankness of the postmortem will determine continued
funding of your project.
The postmortem is an analysis of your project to determine success and
(primarily) failure factors: What you did, what you would do the same,
and what you would do differently next time? Quantitative,
qualitative, and totally subjective measures (e.g., intuition) should
be used. The focus is not on blame, but on improvement. Failure is
inevitable whenever an ambitious project is undertaken. Failing to
learn from it is not. It is recommended to use the description of
Microsoft postmortems in Microsoft Secrets as a template for
your own. A key element of a postmortem is restating the motivation and
objectives for the project: a project is first judged successful
relative to its initial objectives, although success is possible even
if the original objectives were not met if there is considerable
change in direction during the project. History has shown that these
presentations go more smoothly if you have prepared the presentation,
perhaps with slides.
Your postmortem should include feedback from your customers, because
pleasng them is your ultimate goal. Refer back to the MS 1 deliverable
on how to solicit feedback from your customer.
A quality postmortem will benefit from good note-taking throughout the
quarter, although mailing list archives, document revisions, and your
issue-tracking system will be a gold mine. Plan for success of this
element.
Demos and Post-mortem presentations will take place during the time
scheduled for the final. The time will be divided evenly among the
teams (about 20 minutes, if the class isn't too large) plus time for
responses from the project manager and a class postmortem. To provide
context for the other students in the class, provide a description of
your product, its rationale (cf. your vision statement), and a sketch
of the relevant parts of your software development process and methods
before getting into the details of the evaluation.
At the postmortem meeting, provide a softcopy of your notes for the
postmortem (e.g., overhead slides) and a copy of all your documents for
the project (sans source code, which is too big). If all your documents
are on the web, URL's are adequate.
...
The result should be a two-to-six page ``vision document'' for the
product. It is probably too early to address the schedule (more than
what is here) or software.
StringPipe pipe = new StringPipe(filter1, filter2); // connect two filters
while (!pipe.done()) { pipe.run(); }
Here is some simplistic code that shows how such an object could function as a connector:
// A simple architectural connector called a pipe
class StringPipe implements Pipe {
StringFilter in, out;
StringPipe(StringFilter sfIn, StringFilter sfOut) {
in = sfIn; out = sfOut;
}
boolean done() { in.empty(); }
void run() {
out.put(in.get());
}