Made substantial changes. See description for details.