Loading ...
Sorry, an error occurred while loading the content.

Re: [extremeperl] Refactorings?

Expand Messages
  • Ilya Martynov
    ... RN [..snip..] RN TITLE: Replace Conditional with Modifier RN SYNOPSIS RN You have an if statement with a one-line then clause. RN Use a Perl statement
    Message 1 of 14 , Jul 29, 2002
    • 0 Attachment
      >>>>> On Mon, 29 Jul 2002 09:02:54 -0600, Rob Nagler <nagler@...> said:

      RN> [..snip..]

      RN> TITLE: Replace Conditional with Modifier

      RN> SYNOPSIS

      RN> You have an if statement with a one-line then clause.
      RN> Use a Perl statement modifier to keep data flow on the left.

      RN> unless (defined($value)) {
      RN> return undef;
      RN> }

      RN> becomes

      RN> return undef unless defined($value);

      This refactoring is so common that it is even supported by Emacs'
      cperl-mode. Go on first line of if/unless/while etc block and just
      press C-c C-t.

      RN> [..snip..]

      --
      Ilya Martynov (http://martynov.org/)
    • Drew Taylor
      Cool! I didn t know this trick. Hmmm, now I have one more reason I can give my coworker to use emacs instead of vi. ;-) Thanks Ilya! Since you seem to be the
      Message 2 of 14 , Jul 29, 2002
      • 0 Attachment
        Cool! I didn't know this trick. Hmmm, now I have one more reason I can give
        my coworker to use emacs instead of vi. ;-) Thanks Ilya! Since you seem to
        be the author of the cperl-mode bindings, where can I find docs on this
        wonderful mode's feature set?

        Drew

        At 07:29 PM 7/29/02 +0400, Ilya Martynov wrote:

        >This refactoring is so common that it is even supported by Emacs'
        >cperl-mode. Go on first line of if/unless/while etc block and just
        >press C-c C-t.

        ======================================================================
        Drew Taylor | Freelance web development using
        http://www.drewtaylor.com/ | perl/mod_perl/MySQL/postgresql/DBI
        mailto:drew@... | Email jobs at drewtaylor.com
        ----------------------------------------------------------------------
        Speakeasy.net: A DSL provider with a clue. Sign up today.
        http://www.speakeasy.net/refer/29655
        ======================================================================
      • Ilya Martynov
        ... DT Cool! I didn t know this trick. Hmmm, now I have one more reason I DT can give my coworker to use emacs instead of vi. ;-) Thanks Ilya! DT Since you
        Message 3 of 14 , Jul 29, 2002
        • 0 Attachment
          >>>>> On Mon, 29 Jul 2002 11:56:02 -0400, Drew Taylor <drew@...> said:

          DT> Cool! I didn't know this trick. Hmmm, now I have one more reason I
          DT> can give my coworker to use emacs instead of vi. ;-) Thanks Ilya!
          DT> Since you seem to be the author of the cperl-mode bindings, where
          DT> can I find docs on this wonderful mode's feature set?

          Well, I'm not it's author. From cperl.el:

          ;; Author: Ilya Zakharevich and Bob Olson
          ;; Maintainer: Ilya Zakharevich <ilya@...-state.edu>

          As for your question: look under menu Perl/Micro Docs when in buffer
          in cperl-mode. They are not complete but still you may find
          interesting things there.

          Also you can discover many intersing features just by going into
          customize section:

          M-x customize-group [ENTER] cperl [ENTER].

          --
          Ilya Martynov (http://martynov.org/)
        • Ged Haywood
          Hi there, ... Very simple ones. ... I suppose it s my age. I HATE Perl s statement modifiers. And I REALLY REALLY HATE unless . ... Like I said. ...
          Message 4 of 14 , Jul 29, 2002
          • 0 Attachment
            Hi there,

            On Mon, 29 Jul 2002, Rob Nagler wrote:

            > I'm trying to get an idea what people consider useful refactorings.

            Very simple ones.

            > The following refactoring is a very simple one, but I consider it
            > useful to demonstrate how Perl statement modifiers can be used

            I suppose it's my age.
            I HATE Perl's statement modifiers.
            And I REALLY REALLY HATE "unless".

            > I've got a number of other refactorings in my book, but some have said
            > they are too complicated.

            Like I said.

            > Thanks for the feedback.

            :)

            > ----------------------------------------------------------------
            > TITLE: Replace Conditional with Modifier
            >
            > SYNOPSIS
            >
            > You have an if statement with a one-line then clause.
            > Use a Perl statement modifier to keep data flow on the left.
            >
            > unless (defined($value)) {
            > return undef;
            > }
            >
            > becomes
            >
            > return undef unless defined($value);

            Notaroundhereitdoesn't! It becomes

            if(! defined($value) ) { return undef; }

            (and I really mean those curly braces:). (Well, actually, it was
            never "return something unless something" in the first place so the
            refactoring would never have been done anyway:).

            My view would be that undef would be an abnormal condition.
            I usually like my variables to be def. If they aren't def,
            then what's the point of creating them in the first place?
            Ergo, one would test for undef but expect the test to fail.
            Ergo, the return statement should be on the right where it
            doesn't get in the way when you're scanning down the left of
            the page to try to figure out WTBHIGO.

            > This refactoring is controversial, if you aren't used to it.

            Er, run that by me again?

            > It's common to use return, last, die, etc. in Perl. Early exits limit
            > the nesting depth.

            I'd have said early exits prevent program failures and may economize
            on processor cycles, but there we are.

            > Modifiers take this one step further by eliminating all nesting, if
            > possible.

            If eliminating nesting makes it harder to read then give me nesting.

            > The roots of programming are based in logic, not in cooking recipes.
            [snip]
            > This refactoring emulates the declarative style of Prolog.

            Argh++. Declarative is OK where it's OK. I feel it's not OK here.

            > For example, this is the wrong way to use this refactoring:
            >
            > $x = 39, delete($z{$y}) if $is_tuesday; # WRONG USAGE

            Obviously. (But now you're being silly. :)

            73,
            Ged.
          • Rob Nagler
            ... Every refactoring can be implemented in reverse. This is an important part of design by refactoring. This is the art of refactoring imo. The goal is
            Message 5 of 14 , Jul 29, 2002
            • 0 Attachment
              Ged Haywood writes:
              > > return undef unless defined($value);
              >
              > Notaroundhereitdoesn't! It becomes
              >
              > if(! defined($value) ) { return undef; }

              Every refactoring can be implemented in reverse. This is an important
              part of design by refactoring. This is the "art" of refactoring imo.
              The goal is eliminating redunancy in and adding clarity to the design.
              IMO, the extra braces are redundant. The negative test is less
              clear than a parenless unless. Some people like vi, others like emacs.

              Your choice of refactorings is a coding style issue. If your group
              hates unless, then don't use it. This doesn't invalidate the
              refactoring as a concept.

              > My view would be that undef would be an abnormal condition.
              > I usually like my variables to be def. If they aren't def,
              > then what's the point of creating them in the first place?

              Users sometimes don't enter anything. What's the integer value of the
              empty string? Many databases treat the empty string as NULL, which
              means you had better be consistent in your Perl for those databases
              that don't. :-(

              > Ergo, one would test for undef but expect the test to fail.

              The title of the example is "from_literal". You may or may not allow
              undef on a form field. This is a higher level application decision.
              The concept of undef is an important distinguishing factor from Java
              which does not allow undef for native types.

              > Ergo, the return statement should be on the right where it
              > doesn't get in the way when you're scanning down the left of
              > the page to try to figure out WTBHIGO.

              This again is a style issue, ex mea sententia. Some proponents of
              early exit recommend the exit be on the left and others recommend it
              on the right.

              > > This refactoring is controversial, if you aren't used to it.
              >
              > Er, run that by me again?

              If you are familiar with the refactoring, you might not consider it
              controversial. You might think: different strokes for for different
              folks. If you are unfamiliar with it, you might think: what a stupid
              idea. It's the Green Eggs and Ham thing. Try it, you'll like it, or
              at least respect its use by others.

              > > It's common to use return, last, die, etc. in Perl. Early exits limit
              > > the nesting depth.
              >
              > I'd have said early exits prevent program failures and may economize
              > on processor cycles, but there we are.

              This assumes reducing nesting depth prevents program failures. If I
              had made that leap of logic, I would have been blasted. ;-)

              > > Modifiers take this one step further by eliminating all nesting, if
              > > possible.
              >
              > If eliminating nesting makes it harder to read then give me nesting.

              I found Lisp hard to read until I programmed in it. Most people find
              Perl hard to read. Took me a while to get used to unless, but after
              seeing lots of Perl with and without it, my group and I now like it.

              > > The roots of programming are based in logic, not in cooking recipes.
              > [snip]
              > > This refactoring emulates the declarative style of Prolog.
              >
              > Argh++. Declarative is OK where it's OK. I feel it's not OK here.

              As I said, controversial.

              > > For example, this is the wrong way to use this refactoring:
              > >
              > > $x = 39, delete($z{$y}) if $is_tuesday; # WRONG USAGE
              >
              > Obviously. (But now you're being silly. :)

              Here's some code from another reviewer trying to correct what he
              thinks is an incorrect approach elsewhere in the book:

              if (/<[a-z]+[^>]*$/) { s/\n/ /; $_ .= <>};

              Looks quite similar to my example above, but maybe it's just a taste
              thing and mine is silly but this one is serious.

              Every refactoring has its limits. Its important to document where you
              think they are. Every limit has its exceptions. It's important to
              allow yourself to follow your own guidelines. In XP, just make sure
              everybody is in agreement about the limits and exceptions.

              Rob
            • chromatic
              ... I like this one, especially if you demonstrate that it s reversable. I only have one nitpick. ... if undef is intended to return a demonstrably false
              Message 6 of 14 , Jul 29, 2002
              • 0 Attachment
                On Monday 29 July 2002 08:02, Rob Nagler wrote:

                > The following refactoring is a very simple one, but I consider it
                > useful to demonstrate how Perl statement modifiers can be used and to
                > introduce the mechanism by which a document refactorings. The format
                > is borrowed from Fowler's Refactoring book (which I highly recommend,
                > btw).

                I like this one, especially if you demonstrate that it's reversable. I only
                have one nitpick.

                > unless (defined($value)) {
                > return undef;
                > }
                >
                > becomes
                >
                > return undef unless defined($value);

                if 'undef' is intended to return a demonstrably false value, this code is a
                bit broken in list context.

                my @list = undef;
                print "True\n" if @list;

                It's very probably not germane to the example, but a book about good Perl
                development ought to mind context. I generally ask "Did you really mean
                this?" when I see it during code reviews.

                Best,
                -- c
              • Rob Nagler
                ... I hope to avoid showing the reverse of every refactoring. It maybe makes sense to show one or two explicitly. ... No, you need to check if it is undef.
                Message 7 of 14 , Jul 29, 2002
                • 0 Attachment
                  chromatic writes:
                  > I like this one, especially if you demonstrate that it's reversable.

                  I hope to avoid showing the reverse of every refactoring. It maybe
                  makes sense to show one or two explicitly.

                  > if 'undef' is intended to return a demonstrably false value, this code is a
                  > bit broken in list context.
                  >
                  > my @list = undef;
                  > print "True\n" if @list;

                  No, you need to check if it is undef. However, I'm going to change
                  the example to eliminate the "unless" and "undef" parts. They
                  distract from the refactoring which is about statement modifiers.

                  > It's very probably not germane to the example, but a book about good Perl
                  > development ought to mind context. I generally ask "Did you really mean
                  > this?" when I see it during code reviews.

                  I think it is inefficient to write:

                  return wantarray ? () : undef;

                  when the routine returns a scalar. The caller should read the doc or
                  code. If you are building large applications in Perl, you need to
                  respect the declarations. The unit and acceptance tests will help
                  protect against mistakes, but you can't give a kid Perl and say "go
                  write an accounting system". Here's a better description of what I mean:

                  Java was, as Gosling says in the first Java white paper, designed
                  for average programmers. It's a perfectly legitimate goal to
                  design a language for average programmers. (Or for that matter for
                  small children, like Logo.) But it is also a legitimate, and very
                  different, goal to design a language for good programmers.

                  See http://www.paulgraham.com/arcll1.html and other articles by Paul
                  Graham.

                  I think Perl in-the-small is a fine language for just about anybody.
                  Perl in-the-large is another beast entirely. You have to respect
                  interfaces and have an agreed on coding style. I contend you will
                  need OO. You need to build abstractions (e.g. lightweight languages)
                  which map domain knowledge succinctly. The power of Perl in-the-large
                  is that I can let domain experts program Perl in-the-small with
                  "terms" (APIs) developed by Perl experts.

                  Rob
                • chromatic
                  ... That s fine. It s important to demonstrate that you don t always go in one direction. ... The bare return operator respects the calling context: sub false
                  Message 8 of 14 , Jul 29, 2002
                  • 0 Attachment
                    On Monday 29 July 2002 22:09, Rob Nagler wrote:

                    > chromatic writes:
                    > > I like this one, especially if you demonstrate that it's reversable.
                    > I hope to avoid showing the reverse of every refactoring. It maybe
                    > makes sense to show one or two explicitly.

                    That's fine. It's important to demonstrate that you don't always go in one
                    direction.

                    > I think it is inefficient to write:
                    >
                    > return wantarray ? () : undef;
                    >
                    > when the routine returns a scalar. The caller should read the doc or
                    > code.

                    The bare return operator respects the calling context:

                    sub false {
                    return;
                    }

                    my @list = false;
                    my $scalar = false;

                    print "list true" if @list;
                    print "scalar true" if $scalar;
                    print scalar @list;

                    Outside of this example, I do agree that explicit interfaces are important for
                    large applications.

                    > I'm going to change the example to eliminate the "unless" and "undef" parts.
                    > They distract from the refactoring which is about statement modifiers.

                    I think that's wise. They distracted two of us. ;)

                    Regards,
                    -- c
                  • Ged Haywood
                    Hi all, ... 73, Ged.
                    Message 9 of 14 , Jul 30, 2002
                    • 0 Attachment
                      Hi all,

                      On Mon, 29 Jul 2002, chromatic wrote:

                      > On Monday 29 July 2002 22:09, Rob Nagler wrote:
                      >
                      > > I'm going to change the example to eliminate the "unless" and "undef" parts.
                      > > They distract from the refactoring which is about statement modifiers.
                      >
                      > I think that's wise. They distracted two of us. ;)

                      :)

                      73,
                      Ged.
                    • Rob Nagler
                      ... Will do. ... Well, you learn something new everyday. :) Thanks! Rob
                      Message 10 of 14 , Jul 30, 2002
                      • 0 Attachment
                        chromatic writes:
                        > That's fine. It's important to demonstrate that you don't always go in one
                        > direction.

                        Will do.

                        > The bare return operator respects the calling context:

                        Well, you learn something new everyday. :) Thanks!

                        Rob
                      • Stephen Nelson
                        I ve got a few refactorings on my Perlmonks homenode: http://www.perlmonks.org/index.pl?node_id=2329 There are also references to other refactorings there. I d
                        Message 11 of 14 , Jul 30, 2002
                        • 0 Attachment
                          I've got a few refactorings on my Perlmonks homenode:

                          http://www.perlmonks.org/index.pl?node_id=2329

                          There are also references to other refactorings there. I'd appreciate
                          any feedback.

                          Rob Nagler wrote:

                          > I'm trying to get an idea what people consider useful refactorings.
                          >
                          > The following refactoring is a very simple one, but I consider it
                          > useful to demonstrate how Perl statement modifiers can be used and to
                          > introduce the mechanism by which a document refactorings. The format
                          > is borrowed from Fowler's Refactoring book (which I highly recommend,
                          > btw).
                          >
                          > I've got a number of other refactorings in my book, but some have said
                          > they are too complicated. I'll send out a few refactorings later
                          > after I've got some feedback on the format and what your own
                          > refactorings.
                          >
                          > Thanks for the feedback.
                          >
                          > Rob
                          > ----------------------------------------------------------------
                          > TITLE: Replace Conditional with Modifier
                          >
                          > SYNOPSIS
                          >
                          > You have an if statement with a one-line then clause.
                          > Use a Perl statement modifier to keep data flow on the left.
                          >
                          > unless (defined($value)) {
                          > return undef;
                          > }
                          >
                          > becomes
                          >
                          > return undef unless defined($value);
                          >
                          >
                          > MOTIVATION
                          >
                          > This refactoring is controversial, if you aren't used to it.
                          > I find modifiers are a useful programming technique, when they are
                          > available. We use them in natural language prose where it makes
                          > sense. The preceding three sentences are completely normal in
                          > English even if they sound weird all in a row. The fact is on
                          > the left of a qualifying clause. It puts the action up front so
                          > you know what might happen, given a set of circumstances.
                          >
                          > It's common to use return, last, die, etc. in Perl. Early exits limit
                          > the nesting depth. This is a good thing. Modifiers take this one
                          > step further by eliminating all nesting, if possible. This keeps data
                          > flow on the left, which makes it easier to see the side effects, such
                          > as early exit.
                          >
                          > The roots of programming are based in logic, not in cooking recipes.
                          > It seems we often forget this. In mathematical theorems, statements
                          > are often followed by qualifying clauses such as such that and iff.
                          > Most functional languages put the conditional on the left, which is
                          > probably a historical artifact of Lisp, a prefix notation language.
                          > In Prolog, rules are expressed as a fact followed by a condition.
                          > This refactoring emulates the declarative style of Prolog.
                          >
                          > You shouldn't use this refactoring to slam as many separate statements
                          > into a single line as possible. For example, this is the wrong way to
                          > use this refactoring:
                          >
                          > $x = 39, delete($z{$y}) if $is_tuesday; # WRONG USAGE
                          >
                          > This line defeats the motivation of keeping the data flow on the left.
                          > Too much is happening in one line, and the data operations are
                          > complete unrelated. This example obfuscates the data flow instead of
                          > improving it.
                          >
                          > You can convert any if statement into a
                          > do-if, e.g.
                          >
                          > do { # WRONG USAGE
                          > $x = 39;
                          > delete($z{$y});
                          > } if $is_tuesday;
                          >
                          > This doesn't save nesting. There's more code than a simple if
                          > statement. We aren't trying to put all conditionals last. That's as
                          > unnatural as ending all conditional English statements with modifying
                          > clauses.
                          >
                          > MECHANICS
                          >
                          > 1. If the conditional part declares a temporary
                          > my variable, move the declaration part out.
                          >
                          > 2. Remove the braces from the statement and switch the conditional
                          > order. Do not change the conditional logic.
                          >
                          > EXAMPLE
                          >
                          > Here's a method with two one-line if statements:
                          >
                          > sub from_literal {
                          > my(undef, $value) = @_;
                          > unless (defined($value)) {
                          > return undef;
                          > }
                          > $value =~ s/^\s+|\s+$//g;
                          > unless (defined($value)) {
                          > return undef;
                          > }
                          > return $value;
                          > }
                          >
                          > We transform the two conditionals into modified statements:
                          >
                          > sub from_literal {
                          > my(undef, $value) = @_;
                          > return undef unless defined($value);
                          > $value =~ s/^\s+|\s+$//g;
                          > return undef unless length($value);
                          > return $value;
                          > }
                          >
                          >
                          >
                          > Yahoo! Groups Sponsor
                          > ADVERTISEMENT
                          > <http://rd.yahoo.com/M=228862.2128520.3581629.1829184/D=egroupweb/S=1705007181:HM/A=1155069/R=0/*http://adfarm.mediaplex.com/ad/ck/990-1736-1039-302>
                          >
                          >
                          >
                          > To unsubscribe from this group, send an email to:
                          > extremeperl-unsubscribe@yahoogroups.com
                          >
                          >
                          >
                          > Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service
                          > <http://docs.yahoo.com/info/terms/> .
                          > .




                          [Non-text portions of this message have been removed]
                        • Adrian Howard
                          ... [snip] Okay... here s one. (I don t have my Fowler to hand, so please excuse me if I wander off the standard format :-) ... TITLE: HashBecomesObject
                          Message 12 of 14 , Jul 30, 2002
                          • 0 Attachment
                            On Monday, July 29, 2002, at 04:02 pm, Rob Nagler wrote:

                            > I'm trying to get an idea what people consider useful refactorings.
                            [snip]

                            Okay... here's one.

                            (I don't have my Fowler to hand, so please excuse me if I wander off
                            the "standard" format :-)

                            ---

                            TITLE: HashBecomesObject

                            SYNOPSIS:

                            Turn a hash that represents a separate entity into an blessed object
                            that reflects it's purpose.

                            $Tests->{$class}->{$method}->{num_tests} = 4;
                            $Tests->{$class}->{$method}->{type}->{setup} = 1;
                            $Tests->{$class}->{$method}->{type}->{teardown} = 1;

                            becomes:

                            my $info = bless {}, 'Test::MethodInfo';
                            $info->{num_tests} = 4;
                            $info->{type}->{setup} = 1;
                            $info->{type}->{teardown}=1;
                            $Tests->{$class}->{$method} = $info;

                            MOTIVATION:

                            Perl lets you quickly create complex data-structures out of
                            hashes-of-hashes, often acting as simple collections.

                            These can quickly become hard to comprehend, use and maintain.

                            If a part of a hash-of-hashes (or a hash all by it's lonesome) makes
                            sense as a separate entity, turn it into an blessed hash.

                            This acts as a precursor to things like ExtractClass and allows
                            HashAccessBecomesMethodCall for your new object (I'll leave
                            HashAccessBecomesMethodCall, and the obvious ObjectBecomesHash as
                            exercises for the reader :-)

                            ----

                            I'm tempted to stick up a perl refactoring wiki (or is there one
                            already hiding in a corner somewhere?)... Anybody second the
                            suggestion?

                            Adrian
                            --
                            Adrian Howard <adrianh@...>
                            phone: 01929 550720 fax: 0870 131 3033 www.quietstars.com
                          • Stephen Nelson
                            Seconded.... I ve been planning on doing that for way too long. ... [Non-text portions of this message have been removed]
                            Message 13 of 14 , Jul 30, 2002
                            • 0 Attachment
                              Seconded.... I've been planning on doing that for way too long.

                              Adrian Howard wrote:

                              > On Monday, July 29, 2002, at 04:02 pm, Rob Nagler wrote:
                              >
                              > > I'm trying to get an idea what people consider useful refactorings.
                              > [snip]
                              >
                              > Okay... here's one.
                              >
                              > (I don't have my Fowler to hand, so please excuse me if I wander off
                              > the "standard" format :-)
                              >
                              > ---
                              >
                              > TITLE: HashBecomesObject
                              >
                              > SYNOPSIS:
                              >
                              > Turn a hash that represents a separate entity into an blessed object
                              > that reflects it's purpose.
                              >
                              > $Tests->{$class}->{$method}->{num_tests} = 4;
                              > $Tests->{$class}->{$method}->{type}->{setup} = 1;
                              > $Tests->{$class}->{$method}->{type}->{teardown} = 1;
                              >
                              > becomes:
                              >
                              > my $info = bless {}, 'Test::MethodInfo';
                              > $info->{num_tests} = 4;
                              > $info->{type}->{setup} = 1;
                              > $info->{type}->{teardown}=1;
                              > $Tests->{$class}->{$method} = $info;
                              >
                              > MOTIVATION:
                              >
                              > Perl lets you quickly create complex data-structures out of
                              > hashes-of-hashes, often acting as simple collections.
                              >
                              > These can quickly become hard to comprehend, use and maintain.
                              >
                              > If a part of a hash-of-hashes (or a hash all by it's lonesome) makes
                              > sense as a separate entity, turn it into an blessed hash.
                              >
                              > This acts as a precursor to things like ExtractClass and allows
                              > HashAccessBecomesMethodCall for your new object (I'll leave
                              > HashAccessBecomesMethodCall, and the obvious ObjectBecomesHash as
                              > exercises for the reader :-)
                              >
                              > ----
                              >
                              > I'm tempted to stick up a perl refactoring wiki (or is there one
                              > already hiding in a corner somewhere?)... Anybody second the
                              > suggestion?
                              >
                              > Adrian
                              > --
                              > Adrian Howard <adrianh@...>
                              > phone: 01929 550720 fax: 0870 131 3033 www.quietstars.com
                              >
                              >
                              > Yahoo! Groups Sponsor
                              > ADVERTISEMENT
                              > <http://rd.yahoo.com/M=228862.2128520.3581629.1829184/D=egroupweb/S=1705007181:HM/A=1155070/R=0/*http://adfarm.mediaplex.com/ad/ck/990-1736-1039-302>
                              >
                              >
                              >
                              > To unsubscribe from this group, send an email to:
                              > extremeperl-unsubscribe@yahoogroups.com
                              >
                              >
                              >
                              > Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service
                              > <http://docs.yahoo.com/info/terms/> .
                              > .




                              [Non-text portions of this message have been removed]
                            Your message has been successfully submitted and would be delivered to recipients shortly.