← Back to team overview

rapache-devel team mailing list archive

[Merge] lp:~alfred-maghi/rapache/ubuntu-10.04 into lp:rapache

 

Alfred Maghi has proposed merging lp:~alfred-maghi/rapache/ubuntu-10.04 into lp:rapache.

Requested reviews:
  Rapache Developers (rapache-devel)


fix rapache for ubuntu-10.04
-- 
https://code.launchpad.net/~alfred-maghi/rapache/ubuntu-10.04/+merge/25398
Your team Rapache Developers is requested to review the proposed merge of lp:~alfred-maghi/rapache/ubuntu-10.04 into lp:rapache.
=== added file 'AUTHORS'
--- AUTHORS	1970-01-01 00:00:00 +0000
+++ AUTHORS	2010-05-16 16:14:24 +0000
@@ -0,0 +1,39 @@
+ Copyright (C) Rapache Developers 2008 <rapache-devel@xxxxxxxxxxxxxxxxxxx>
+
+ This file is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ main.py is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+Rapache Developers Team:
+
+ * Stefano Forenza <tacone@xxxxxxxxx>
+ * Emanuele Gentili <emgent@xxxxxxxxxx>
+ * Damiano Di Carlo <damianodicarlo@xxxxxxxxx>
+ * Luana Polleggioni <luana@xxxxxxxxxxxxxx>
+ * Jason Tyler <killerkiwi2005@xxxxxxxxx>
+
+Special thanks to (contributors):
+
+ * Andrew H (rugby471)
+ * Sense Hofstede (qense)
+
+Other credits:
+
+glade/browser.png icon taken from browser.svg in Neu theme:
+License: GPL-2
+Homepage: http://www.silvestre.com.ar/
+Name: Silvestre Herrera
+Nickname: ertz
+Location: La Plata, Buenos Aires. ARGENTINA.
+E-mail: silvestre.herrera(at)gmail.com
+Website(s): http://www.silvestre.com.ar/
\ No newline at end of file

=== renamed file 'AUTHORS' => 'AUTHORS.moved'
=== added file 'COPYING'
--- COPYING	1970-01-01 00:00:00 +0000
+++ COPYING	2010-05-16 16:14:24 +0000
@@ -0,0 +1,676 @@
+
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+ 
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+  
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+

=== renamed file 'COPYING' => 'COPYING.moved'
=== added directory 'Glade'
=== renamed directory 'Glade' => 'Glade.moved'
=== added file 'Glade/apache.lang'
--- Glade/apache.lang	1970-01-01 00:00:00 +0000
+++ Glade/apache.lang	2010-05-16 16:14:24 +0000
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Original version (Ini file highlighting)
+ Author: Antonio Ognio <gnrfan@xxxxxxxxxx>
+ Copyright (C) 2005 Antonio Ognio <gnrfan@xxxxxxxxxx>
+
+ Hacks to support Apache Conf files (adding tag context, support of identation, changing comment char to "#")
+ Author: Stefano Forenza <tacone@xxxxxxxxx>
+ Copyright (C) 2008 Stefano Forenza <tacone@xxxxxxxxx>
+ 
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+-->
+<language id="apache" _name="Apache Confs" version="2.0" _section="Others">
+  <metadata>
+    <property name="mimetypes">text/plain</property>
+    <property name="globs">*.*</property>
+    <property name="line-comment-start">#</property>
+  </metadata>
+
+  <styles>
+    <style id="comment" _name="Comment" map-to="def:comment"/>
+    <style id="floating-point" _name="Floating Point" map-to="def:floating-point"/>
+    <style id="string" _name="String" map-to="def:string"/>
+    <style id="keyword" _name="Keyword" map-to="def:keyword"/>
+    <style id="tag" _name="Tag" map-to="def:keyword"/>
+    <style id="decimal" _name="Decimal" map-to="def:decimal"/>
+    <style id="variable" _name="Variable" map-to="def:type"/>
+    <style id="non-standard-key" _name="Data Type" map-to="def:type"/>
+    <style id="boolean-value" _name="Boolean value" map-to="def:boolean"/>
+  </styles>
+  <default-regex-options case-sensitive="false" />
+  
+  <definitions>
+    <context id="line-comment" style-ref="comment" end-at-line-end="true">
+      <start>#</start>
+    </context>
+    <context id="group" style-ref="keyword">
+      <start>^\[</start>
+      <end>\]$</end>
+    </context>
+    <context id="tag">
+		<start>&lt;\s*/?\s*[a-zA-Z0-9_]+</start>
+		<end>/?\s*&gt;</end>
+		<include>
+		    <context sub-pattern="0" where="start" style-ref="tag"/>
+		    <context ref="tag_attributes"/>
+		    <context sub-pattern="0" where="end" style-ref="tag"/>		    
+		</include>
+	</context>
+	<context id="tag_attributes" style-ref="string">
+      <match>[^&gt;]+</match>
+    </context>
+    <context id="non-standard-key" style-ref="non-standard-key">
+      <match>^_?X\-[a-zA-Z\-]+</match>
+    </context>
+    <context id="language" style-ref="decimal">
+      <match>\[[a-zA-Z_]+\]</match>
+    </context>
+    <context id="variable" style-ref="variable">
+      <match>^\s*[a-zA-Z_][a-zA-Z0-9_.]*</match>
+    </context>
+    <context id="boolean-value" style-ref="boolean-value">
+      <keyword>on</keyword>
+      <keyword>off</keyword>
+      
+    </context>
+    <context id="single-quoted-string" style-ref="string">
+      <start>'</start>
+      <end>'</end>
+    </context>
+    <context id="double-quoted-string" style-ref="string">
+      <start>"</start>
+      <end>"</end>
+    </context>
+    <context id="integer" style-ref="decimal">
+      <match>\b[0-9]+\b</match>
+    </context>
+    <context id="decimal-number" style-ref="floating-point">
+      <match>(\b[0-9]+(\.[0-9]+)?|\.[0-9]+)([Ee][\+-]?[0-9]+)?\b</match>
+    </context>
+    <context id="apache">
+      <include>
+        <context ref="line-comment"/>
+        <context ref="group"/>
+        <context ref="non-standard-key"/>
+        <context ref="language"/>
+        <context ref="variable"/>
+        <context ref="boolean-value"/>
+        <context ref="single-quoted-string"/>
+        <context ref="double-quoted-string"/>
+        <context ref="decimal-number"/>
+        <context ref="integer"/>
+        <context ref="tag"/>
+      </include>
+    </context>
+  </definitions>
+</language>

=== added file 'Glade/browser.png'
Binary files Glade/browser.png	1970-01-01 00:00:00 +0000 and Glade/browser.png	2010-05-16 16:14:24 +0000 differ
=== added file 'Glade/confirmation.glade'
--- Glade/confirmation.glade	1970-01-01 00:00:00 +0000
+++ Glade/confirmation.glade	2010-05-16 16:14:24 +0000
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Sat Jul 26 17:53:35 2008 -->
+<glade-interface>
+  <widget class="GtkDialog" id="confirmation_window">
+    <property name="border_width">5</property>
+    <property name="modal">True</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="destroy_with_parent">True</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="has_separator">False</property>
+    <signal name="destroy" handler="on_destroy"/>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <child>
+              <widget class="GtkLabel" id="question_label">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Do you want to proceed ?</property>
+                <property name="use_markup">True</property>
+                <property name="wrap">True</property>
+              </widget>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="cancel_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+                <signal name="clicked" handler="on_cancel_button_clicked"/>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="ok_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+                <signal name="clicked" handler="on_ok_button_clicked"/>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>

=== added file 'Glade/edit_domain_name.glade'
--- Glade/edit_domain_name.glade	1970-01-01 00:00:00 +0000
+++ Glade/edit_domain_name.glade	2010-05-16 16:14:24 +0000
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Thu Jul  3 04:38:32 2008 -->
+<glade-interface>
+  <widget class="GtkDialog" id="dialog_edit_domain_name">
+    <property name="border_width">5</property>
+    <property name="modal">True</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="default_width">400</property>
+    <property name="destroy_with_parent">True</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="urgency_hint">True</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox2">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkHBox" id="hbox8">
+            <property name="visible">True</property>
+            <child>
+              <widget class="GtkImage" id="image_icon">
+                <property name="visible">True</property>
+                <property name="stock">gtk-edit</property>
+                <property name="icon_size">5</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="padding">8</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox2">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label_heading">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Enter your domain name</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="padding">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkEntry" id="entry_domain">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="has_focus">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="padding">8</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area2">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="button_cancel">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+                <signal name="clicked" handler="on_button_cancel_clicked"/>
+                <accelerator key="Escape" modifiers="" signal="clicked"/>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button_ok">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+                <signal name="clicked" handler="on_button_ok_clicked"/>
+                <accelerator key="Return" modifiers="" signal="clicked"/>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>

=== added file 'Glade/edit_module.glade'
--- Glade/edit_module.glade	1970-01-01 00:00:00 +0000
+++ Glade/edit_module.glade	2010-05-16 16:14:24 +0000
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Mon Jul 21 21:16:58 2008 -->
+<glade-interface>
+  <widget class="GtkDialog" id="dialog_edit_module">
+    <property name="width_request">600</property>
+    <property name="height_request">400</property>
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">Module Configuration Editor</property>
+    <property name="modal">True</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkHBox" id="error_area">
+            <child>
+              <widget class="GtkImage" id="image1">
+                <property name="visible">True</property>
+                <property name="stock">gtk-dialog-error</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="message_text">
+                <property name="visible">True</property>
+                <property name="ypad">10</property>
+                <property name="label" translatable="yes">Error: Unknown error.</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkNotebook" id="notebook">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <child>
+              <widget class="GtkScrolledWindow" id="text_view_module_conf_area">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                <child>
+                  <placeholder/>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox4">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkImage" id="image6">
+                    <property name="visible">True</property>
+                    <property name="stock">gtk-file</property>
+                    <property name="icon_size">1</property>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label8">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Definition File</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="type">tab</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="padding">8</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="module_doc_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-help</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+                <signal name="clicked" handler="on_module_doc_button_clicked"/>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button_cancel">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+                <signal name="clicked" handler="on_button_cancel_clicked"/>
+                <accelerator key="Escape" modifiers="" signal="activate"/>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button_save">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="is_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-save</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+                <signal name="clicked" handler="on_button_save_clicked"/>
+              </widget>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>

=== added file 'Glade/edit_vhost.glade'
--- Glade/edit_vhost.glade	1970-01-01 00:00:00 +0000
+++ Glade/edit_vhost.glade	2010-05-16 16:14:24 +0000
@@ -0,0 +1,944 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Tue Jul 22 13:54:02 2008 -->
+<glade-interface>
+  <widget class="GtkWindow" id="vhost_edit_window">
+    <property name="border_width">10</property>
+    <property name="title" translatable="yes">New Virtual Host</property>
+    <property name="modal">True</property>
+    <property name="window_position">GTK_WIN_POS_CENTER</property>
+    <signal name="destroy" handler="quit"/>
+    <child>
+      <widget class="GtkNotebook" id="notebook_old">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <child>
+          <widget class="GtkVPaned" id="vpaned1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <widget class="GtkTable" id="table1">
+                <property name="visible">True</property>
+                <property name="n_rows">5</property>
+                <property name="n_columns">2</property>
+                <property name="column_spacing">10</property>
+                <property name="row_spacing">10</property>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <widget class="GtkVBox" id="vbox1">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkCheckButton" id="set_custom_folder">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="label" translatable="yes">Let me choose custom _folder</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
+                        <signal name="toggled" handler="custom_folder_toggled"/>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkFileChooserButton" id="custom_folder">
+                        <property name="title" translatable="yes">Select A Folder</property>
+                      </widget>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkEntry" id="default_folder">
+                        <property name="visible">True</property>
+                        <property name="sensitive">False</property>
+                        <property name="can_focus">True</property>
+                        <property name="editable">False</property>
+                        <property name="truncate_multiline">True</property>
+                      </widget>
+                      <packing>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="create_hosts_entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Add an entry to /etc/_hosts</property>
+                    <property name="use_underline">True</property>
+                    <property name="response_id">0</property>
+                    <property name="active">True</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="create_hosts_label">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">To access your Virtual Host 
+you either need a registered
+domain name or an entry in
+&lt;b&gt;/etc/hosts&lt;/b&gt;.</property>
+                    <property name="use_markup">True</property>
+                    <property name="wrap">True</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label5">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Target folder:</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkButton" id="ok_button">
+                    <property name="visible">True</property>
+                    <property name="sensitive">False</property>
+                    <property name="can_focus">True</property>
+                    <property name="is_focus">True</property>
+                    <property name="can_default">True</property>
+                    <property name="has_default">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="label" translatable="yes">gtk-save</property>
+                    <property name="use_stock">True</property>
+                    <property name="response_id">0</property>
+                    <signal name="clicked" handler="on_ok"/>
+                    <accelerator key="Return" modifiers="" signal="clicked"/>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">4</property>
+                    <property name="bottom_attach">5</property>
+                    <property name="x_options">GTK_EXPAND</property>
+                    <property name="y_options">GTK_EXPAND</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkButton" id="cancel_button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="label" translatable="yes">gtk-cancel</property>
+                    <property name="use_stock">True</property>
+                    <property name="response_id">0</property>
+                    <signal name="clicked" handler="on_cancel"/>
+                    <accelerator key="Escape" modifiers="" signal="activate"/>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">4</property>
+                    <property name="bottom_attach">5</property>
+                    <property name="x_options">GTK_EXPAND</property>
+                    <property name="y_options">GTK_EXPAND</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label6">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Domain name:
+(no http:// or www)</property>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="has_www">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Create _www</property>
+                    <property name="use_underline">True</property>
+                    <property name="response_id">0</property>
+                    <property name="active">True</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkEntry" id="domain_name">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="has_focus">True</property>
+                    <property name="is_focus">True</property>
+                    <signal name="delete_from_cursor" handler="domain_name_updated"/>
+                    <signal name="changed" handler="domain_name_updated"/>
+                    <signal name="delete_text" handler="domain_name_updated"/>
+                    <signal name="insert_text" handler="domain_name_updated"/>
+                    <signal name="activate" handler="domain_name_updated"/>
+                    <signal name="paste_clipboard" handler="domain_name_updated"/>
+                    <signal name="copy_clipboard" handler="domain_name_updated"/>
+                    <signal name="cut_clipboard" handler="domain_name_updated"/>
+                    <signal name="insert_at_cursor" handler="domain_name_updated"/>
+                    <signal name="backspace" handler="domain_name_updated"/>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="resize">True</property>
+                <property name="shrink">True</property>
+              </packing>
+            </child>
+          </widget>
+        </child>
+        <child>
+          <widget class="GtkHBox" id="hbox2">
+            <property name="visible">True</property>
+            <child>
+              <widget class="GtkImage" id="image3">
+                <property name="visible">True</property>
+                <property name="stock">gtk-properties</property>
+                <property name="icon_size">1</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Details</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="type">tab</property>
+            <property name="tab_fill">False</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkScrolledWindow" id="scrolledwindow1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+            <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+            <child>
+              <widget class="GtkTextView" id="vhost_source">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="editable">False</property>
+                <property name="indent">1</property>
+                <property name="text" translatable="yes">Once created, the vhost definition will be visible here</property>
+              </widget>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkHBox" id="hbox1">
+            <property name="visible">True</property>
+            <child>
+              <widget class="GtkImage" id="image2">
+                <property name="visible">True</property>
+                <property name="stock">gtk-file</property>
+                <property name="icon_size">1</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label2">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Virtual Host definition</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="type">tab</property>
+            <property name="position">1</property>
+            <property name="tab_fill">False</property>
+          </packing>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+          <packing>
+            <property name="type">tab</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+  <widget class="GtkDialog" id="dialog_edit_vhost">
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">VirtualHost Editor</property>
+    <property name="modal">True</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkHBox" id="error_area">
+            <child>
+              <widget class="GtkImage" id="image1">
+                <property name="visible">True</property>
+                <property name="stock">gtk-dialog-error</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="message_text">
+                <property name="visible">True</property>
+                <property name="ypad">10</property>
+                <property name="label" translatable="yes">Error: Virtual Host creation aborted.</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkNotebook" id="notebook">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <child>
+              <widget class="GtkTable" id="table2">
+                <property name="visible">True</property>
+                <property name="n_rows">5</property>
+                <property name="n_columns">2</property>
+                <property name="column_spacing">10</property>
+                <property name="row_spacing">10</property>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <widget class="GtkHBox" id="hbox5">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkEntry" id="entry_location">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="truncate_multiline">True</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkButton" id="button_location">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="response_id">0</property>
+                        <signal name="clicked" handler="on_button_location_clicked"/>
+                        <child>
+                          <widget class="GtkHBox" id="hbox7">
+                            <property name="visible">True</property>
+                            <child>
+                              <widget class="GtkImage" id="image8">
+                                <property name="visible">True</property>
+                                <property name="stock">gtk-directory</property>
+                              </widget>
+                            </child>
+                          </widget>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkButton" id="button_location_clear">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="response_id">0</property>
+                        <signal name="clicked" handler="on_button_location_clear_clicked"/>
+                        <child>
+                          <widget class="GtkImage" id="image4">
+                            <property name="visible">True</property>
+                            <property name="stock">gtk-clear</property>
+                          </widget>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkViewport" id="viewport1">
+                    <property name="visible">True</property>
+                    <property name="resize_mode">GTK_RESIZE_QUEUE</property>
+                    <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+                    <child>
+                      <widget class="GtkVBox" id="vbox3">
+                        <property name="visible">True</property>
+                        <child>
+                          <widget class="GtkHBox" id="hbox6">
+                            <property name="visible">True</property>
+                            <child>
+                              <widget class="GtkLabel" id="label12">
+                                <property name="visible">True</property>
+                                <property name="label" translatable="yes">Additional Domains</property>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="padding">8</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <placeholder/>
+                            </child>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="padding">8</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkToolbar" id="toolbar2">
+                            <property name="visible">True</property>
+                            <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
+                            <child>
+                              <widget class="GtkToolButton" id="toolbutton_domain_add">
+                                <property name="visible">True</property>
+                                <property name="label" translatable="yes">Add</property>
+                                <property name="stock_id">gtk-add</property>
+                                <signal name="clicked" handler="on_toolbutton_domain_add_clicked"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkToolButton" id="toolbutton_domain_edit">
+                                <property name="visible">True</property>
+                                <property name="label" translatable="yes">Edit</property>
+                                <property name="stock_id">gtk-edit</property>
+                                <signal name="clicked" handler="on_toolbutton_domain_edit_clicked"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkToolButton" id="toolbutton_domain_delete">
+                                <property name="visible">True</property>
+                                <property name="label" translatable="yes">Delete</property>
+                                <property name="stock_id">gtk-delete</property>
+                                <signal name="clicked" handler="on_toolbutton_domain_delete_clicked"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                              </packing>
+                            </child>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkScrolledWindow" id="scrolledwindow4">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                            <child>
+                              <widget class="GtkTreeView" id="treeview_domain">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="headers_visible">False</property>
+                                <property name="headers_clickable">True</property>
+                              </widget>
+                            </child>
+                          </widget>
+                          <packing>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                      </widget>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                    <property name="x_padding">8</property>
+                    <property name="y_padding">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="checkbutton_hosts">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Add proper entries to /etc/_hosts</property>
+                    <property name="use_underline">True</property>
+                    <property name="response_id">0</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">4</property>
+                    <property name="bottom_attach">5</property>
+                    <property name="y_options"></property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="create_hosts_label1">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">If you have a domain that is not registered you will need an entry in your &lt;b&gt;/etc/hosts&lt;/b&gt; file.</property>
+                    <property name="use_markup">True</property>
+                    <property name="wrap">True</property>
+                  </widget>
+                  <packing>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                    <property name="y_options"></property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label4">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Location:</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                    <property name="x_options"></property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label3">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Domain name:</property>
+                  </widget>
+                  <packing>
+                    <property name="x_options"></property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">8</property>
+                    <property name="y_padding">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkEntry" id="entry_domain">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="has_focus">True</property>
+                    <property name="is_focus">True</property>
+                    <signal name="changed" handler="on_entry_domain_changed"/>
+                    <signal name="focus_out_event" handler="on_entry_domain_focus_out_event"/>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">8</property>
+                    <property name="y_padding">8</property>
+                  </packing>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox3">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkImage" id="image5">
+                    <property name="visible">True</property>
+                    <property name="stock">gtk-properties</property>
+                    <property name="icon_size">1</property>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label7">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Domain</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="type">tab</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label17">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">basic security......</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox9">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkImage" id="image7">
+                    <property name="visible">True</property>
+                    <property name="stock">gtk-dialog-authentication</property>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label16">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Security</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="type">tab</property>
+                <property name="position">2</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkTable" id="table4">
+                <property name="visible">True</property>
+                <property name="n_rows">4</property>
+                <property name="n_columns">2</property>
+                <child>
+                  <widget class="GtkLabel" id="label14">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Log File Location</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">8</property>
+                    <property name="y_padding">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label13">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Server signature</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                    <property name="y_options">GTK_FILL</property>
+                    <property name="x_padding">8</property>
+                    <property name="y_padding">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label11">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Server Admin Email</property>
+                  </widget>
+                  <packing>
+                    <property name="y_options"></property>
+                    <property name="x_padding">8</property>
+                    <property name="y_padding">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkEntry" id="entry_admin_email">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="y_options"></property>
+                    <property name="x_padding">8</property>
+                    <property name="y_padding">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkComboBox" id="combobox_log_level">
+                    <property name="visible">True</property>
+                    <property name="items" translatable="yes">Emergencies - system is unusable
+Action must be taken immediately
+Critical Conditions
+Error conditions
+Warning conditions
+Normal but significant condition
+Informational
+Debug-level messages</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                    <property name="y_options">GTK_FILL</property>
+                    <property name="x_padding">8</property>
+                    <property name="y_padding">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label10">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Error Log Level</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                    <property name="y_options">GTK_FILL</property>
+                    <property name="x_padding">8</property>
+                    <property name="y_padding">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="checkbutton_server_signature">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Include server signature</property>
+                    <property name="response_id">0</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                    <property name="y_options">GTK_FILL</property>
+                    <property name="x_padding">7</property>
+                    <property name="y_padding">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkHBox" id="hbox11">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkEntry" id="entry_log_location">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkButton" id="button_log_location">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="response_id">0</property>
+                        <child>
+                          <widget class="GtkImage" id="image10">
+                            <property name="visible">True</property>
+                            <property name="stock">gtk-directory</property>
+                          </widget>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="padding">8</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                    <property name="y_options">GTK_FILL</property>
+                    <property name="x_padding">8</property>
+                    <property name="y_padding">8</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox10">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkImage" id="image9">
+                    <property name="visible">True</property>
+                    <property name="stock">gtk-edit</property>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label9">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Advanced</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="type">tab</property>
+                <property name="position">2</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox2">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label15">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">File: /var/www/config/whatever.host</property>
+                    <property name="selectable">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="padding">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkHBox" id="hbox8">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkScrolledWindow" id="text_view_vhost_source_area">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                        <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+                        <child>
+                          <placeholder/>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="padding">8</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="padding">8</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox4">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkImage" id="image6">
+                    <property name="visible">True</property>
+                    <property name="stock">gtk-file</property>
+                    <property name="icon_size">1</property>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label8">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Definition File</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="type">tab</property>
+                <property name="position">3</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="padding">8</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="button_cancel">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+                <signal name="clicked" handler="on_button_cancel_clicked"/>
+                <accelerator key="Escape" modifiers="" signal="activate"/>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button_save">
+                <property name="visible">True</property>
+                <property name="sensitive">False</property>
+                <property name="can_focus">True</property>
+                <property name="is_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-save</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+                <signal name="clicked" handler="on_button_save_clicked"/>
+                <accelerator key="Return" modifiers="" signal="clicked"/>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>

=== added file 'Glade/icon_cadsoft_eagle.svg'
--- Glade/icon_cadsoft_eagle.svg	1970-01-01 00:00:00 +0000
+++ Glade/icon_cadsoft_eagle.svg	2010-05-16 16:14:24 +0000
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://web.resource.org/cc/";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:xlink="http://www.w3.org/1999/xlink";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   id="svg2244"
+   sodipodi:version="0.32"
+   inkscape:version="0.45.1"
+   width="256"
+   height="256"
+   version="1.0"
+   sodipodi:docbase="C:\Users\svo\Pictures"
+   sodipodi:docname="eaglev1.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   inkscape:export-filename="C:\Users\svo\Pictures\cadsoft_eagle.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <metadata
+     id="metadata2249">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs2247">
+    <linearGradient
+       id="linearGradient3351">
+      <stop
+         style="stop-color:#ff1616;stop-opacity:1;"
+         offset="0"
+         id="stop3353" />
+      <stop
+         id="stop3359"
+         offset="0.84745765"
+         style="stop-color:#fe1b1b;stop-opacity:0.77222222;" />
+      <stop
+         style="stop-color:#fc0000;stop-opacity:0.69999999;"
+         offset="1"
+         id="stop3355" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3351"
+       id="linearGradient3361"
+       x1="41.519562"
+       y1="126.612"
+       x2="217.06261"
+       y2="126.612"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <sodipodi:namedview
+     inkscape:window-height="691"
+     inkscape:window-width="1069"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     width="256px"
+     height="256px"
+     inkscape:zoom="1.1489362"
+     inkscape:cx="141.86443"
+     inkscape:cy="154.04182"
+     inkscape:window-x="94"
+     inkscape:window-y="20"
+     inkscape:current-layer="g2259" />
+  <g
+     id="g2259"
+     transform="translate(-3.0111111e-6,-1.8518517e-7)">
+    <g
+       id="g2357"
+       transform="translate(-610.12961,-12.277778)">
+      <path
+         style="opacity:1;fill:#010101"
+         d="M 759.54278,17.326388 C 748.11048,31.811337 743.26528,50.49121 733.82409,66.263887 C 730.67889,69.571656 727.95919,74.546797 725.88659,77.076387 C 724.36049,80.993521 720.29659,78.366198 715.60119,84.780336 C 712.06259,88.397654 708.86829,92.225456 706.07409,96.451386 C 706.75959,93.106686 706.67099,86.373303 701.57409,88.326387 C 696.05749,94.213176 693.82319,103.27019 689.66779,109.88889 C 690.04409,105.54812 692.95819,100.59003 690.26159,96.513886 C 684.02257,95.681976 683.50591,104.08909 680.66782,107.76389 C 675.94709,119.5509 668.33083,130.90077 667.91782,143.88889 C 667.81707,153.59339 676.17733,159.71374 683.26157,164.73264 C 685.72067,166.6766 685.23092,170.46469 681.51157,170.17014 C 668.52044,173.68863 659.01136,184.71317 652.91782,196.10764 C 650.99657,201.59319 651.56967,207.86036 649.35532,213.01389 C 650.23499,217.87253 657.47944,224.02339 661.41782,218.76389 C 662.18127,215.98023 661.13448,212.67366 664.48032,210.92014 C 669.63355,206.98131 677.66196,202.75363 684.13657,205.98264 C 687.62659,208.92365 691.55499,212.16613 694.60529,215.38889 C 694.72249,221.75271 695.53519,229.2592 693.57409,234.98264 C 687.00259,238.14468 678.87551,237.33995 673.91782,243.51389 C 671.51138,245.29557 673.56967,248.68938 670.01157,249.04514 C 665.66927,250.31745 666.72321,256.56446 671.29282,256.26389 C 673.85889,255.90755 674.84956,256.47146 675.23032,259.04514 C 676.49263,262.95857 680.57145,260.63059 681.29282,257.82639 C 684.27954,255.73528 688.2276,251.6877 691.69909,255.32639 C 695.09669,255.27642 694.97359,261.5318 698.51159,258.79514 C 701.14199,257.86809 699.91439,253.35785 700.48029,252.23264 C 703.23709,255.91833 708.02789,252.05157 706.13659,248.32639 C 707.59619,245.45134 711.58439,249.71807 714.04279,249.54514 C 718.27269,251.1571 719.07689,246.25678 721.98029,244.60764 C 724.93839,242.48899 726.03819,239.20098 727.13659,236.04514 C 731.48589,236.58521 737.19799,237.35988 739.63659,232.95139 C 743.02778,233.52963 745.81768,229.50029 743.16778,227.04514 C 745.84338,226.34096 746.38778,223.53443 747.35528,221.73264 C 751.78368,219.82541 757.99818,225.56373 761.29278,220.57639 C 763.09178,218.28761 764.46808,217.74857 767.57408,218.45139 C 771.73618,219.67501 774.62528,214.72053 771.54278,211.70139 C 770.88698,209.7168 764.51958,207.29714 769.10528,207.01389 C 774.36078,205.6766 779.69458,211.56993 784.26158,208.76389 C 785.50088,205.92029 784.01388,203.91799 788.88658,204.76389 C 799.24248,204.06933 810.05538,204.43855 819.98028,201.82639 C 823.81168,202.21722 831.47348,200.42144 828.54278,195.10764 C 825.45278,193.736 830.93548,191.38095 829.38658,188.67014 C 828.66168,185.04186 824.26808,185.27737 821.60528,185.23264 C 824.90398,182.22649 821.22798,177.75011 817.63658,178.67014 C 817.07648,175.8906 819.46268,173.04288 817.73028,170.42014 C 814.33138,167.77249 810.60058,170.01623 806.79278,169.23264 C 793.19058,173.56224 779.72028,178.45769 765.28068,179.66471 C 760.89998,181.38932 763.43728,175.77006 766.60528,176.73264 C 771.39538,174.87038 779.24718,178.07672 781.85528,172.48264 C 782.47028,170.23734 779.74748,167.65209 783.26158,166.82639 C 786.18848,166.00396 787.97528,163.45248 788.91778,160.88889 C 791.36308,159.94146 793.44118,157.20766 792.73028,154.82639 C 796.06648,155.43925 796.44948,150.86982 796.10528,149.85764 C 800.16798,150.45133 801.13908,145.36863 798.66778,143.29514 C 802.10538,141.37856 801.32558,135.82731 797.44908,135.29514 C 801.04088,131.58211 796.17078,127.19127 795.76158,123.85764 C 798.08098,121.63745 803.12878,121.88556 803.10528,117.63889 C 807.63048,113.76118 802.21208,109.00533 798.69908,107.17014 C 796.93588,105.63055 791.55638,103.74356 796.82408,104.13889 C 801.78478,104.74324 805.44028,98.338026 802.13658,95.451386 C 807.43558,93.715826 814.88738,94.194406 818.19908,89.045137 C 818.21068,83.11118 810.27278,83.666657 806.14028,82.834249 C 800.60178,82.119611 793.44928,82.476225 788.85528,82.295137 C 797.99558,77.20914 806.61968,71.007879 814.35528,64.232637 C 818.13088,61.040164 818.62268,55.924034 820.04278,51.482637 C 807.19198,55.739162 795.38368,62.193713 782.98028,67.482637 C 792.67148,59.153621 799.67928,48.503353 808.57408,39.420137 C 812.26418,37.31039 812.35178,30.386018 807.01158,31.451387 C 801.10998,32.852912 796.88008,37.724345 791.04278,39.076387 C 787.29158,41.040179 782.94098,44.598175 780.19908,46.420137 C 786.48348,37.760557 795.96408,31.468921 801.63658,22.388887 C 801.18298,16.643849 794.51338,18.983045 791.76158,21.576387 C 780.01878,30.352629 768.69638,39.758322 757.60528,49.201387 C 757.22318,41.369421 762.68078,35.196654 763.51158,27.545137 C 764.29338,23.945952 766.32568,16.266474 760.32408,16.763888 L 759.54278,17.326388 z "
+         id="path2372" />
+    </g>
+    <path
+       style="fill:url(#linearGradient3361);fill-opacity:1.0;stroke:#cca321;stroke-opacity:0.63636363;stroke-width:1.1;stroke-miterlimit:4;stroke-dasharray:none;opacity:1"
+       d="M 67.337805,244.81481 C 67.025655,243.98981 67.175275,242.52731 67.670305,241.56481 C 68.569635,239.81623 67.503625,239.14451 66.083325,240.56481 C 65.027085,241.62106 59.437175,241.50328 59.794165,240.43231 C 59.955955,239.94693 62.093455,238.80912 64.544165,237.90383 C 68.937785,236.28084 69.893025,234.08513 65.999995,234.55747 C 64.441275,234.74658 64.772225,234.14576 67.499995,231.83437 C 69.424995,230.2032 71.815445,228.85651 72.812095,228.84171 C 75.193985,228.80635 84.654445,225.77773 86.249995,224.53977 C 87.628275,223.47039 88.104355,200.84491 86.749995,200.77746 C 86.337495,200.75692 83.350215,198.28192 80.111595,195.27746 C 74.865465,190.41064 73.751545,189.81481 69.899105,189.81481 C 59.921445,189.81481 47.750275,197.75104 48.811815,203.56481 C 49.104685,205.16875 48.739975,205.81481 47.541655,205.81481 C 45.346795,205.81481 40.923995,200.78883 42.345665,199.91019 C 42.924865,199.55223 43.698785,196.12183 44.065485,192.28708 C 44.813345,184.46654 45.446735,183.20735 53.635155,173.26257 C 59.393205,166.26944 64.523485,162.96712 73.990285,160.16013 C 79.477025,158.53326 78.550935,152.1346 72.253365,148.15912 C 61.133295,141.13933 58.262955,133.42062 62.422015,121.72136 C 66.329445,110.72989 78.298235,85.018682 78.438545,87.314812 C 78.578625,89.607102 75.441205,103.77525 73.487665,109.67228 C 72.329335,113.16889 71.569115,116.21726 71.798295,116.44645 C 72.723845,117.37199 75.418285,112.68312 84.166395,94.923562 C 92.906115,77.181014 93.331675,76.524281 93.308915,80.814812 C 93.280455,86.177642 91.486555,92.960672 88.600665,98.617479 C 87.445295,100.88219 86.499995,102.99372 86.499995,103.30977 C 86.499995,104.89283 92.424905,96.493712 95.499995,90.551422 C 97.424995,86.831552 101.3872,81.206562 104.3049,78.051424 L 109.60981,72.314816 L 105.89062,79.314816 C 103.84507,83.164812 101.73124,86.888192 101.19321,87.588982 C 100.65519,88.289772 100.46205,89.110202 100.76401,89.412162 C 101.37591,90.024062 108.91476,80.046052 118.31173,66.186954 C 121.71568,61.166629 125.12832,56.538245 125.89537,55.901655 C 126.66241,55.265065 130.29593,48.122603 133.96985,40.029517 C 141.54994,23.331741 145.78124,14.962793 149.16297,9.9795277 C 151.32177,6.7983516 151.49728,6.7179516 151.46438,8.9252687 C 151.39644,13.482619 148.13431,25.093143 146.22994,27.55564 C 145.70216,28.238094 145.09343,31.061342 144.87721,33.829525 C 144.66099,36.597708 144.37516,39.358087 144.24204,39.963701 C 143.6445,42.682118 146.82988,41.594637 151.2159,37.582844 C 153.84716,35.176095 158.025,31.661673 160.5,29.773017 C 162.975,27.884362 168.825,23.13746 173.5,19.224346 C 182.22627,11.9202 188.5,7.9734757 188.5,9.7880367 C 188.5,10.351557 183.775,15.549085 178,21.3381 C 172.225,27.127115 167.5,32.302609 167.5,32.839199 C 167.5,33.375788 166.77686,33.814816 165.89301,33.814816 C 164.83155,33.814816 164.49421,34.357347 164.8993,35.412988 C 165.26645,36.369778 164.46105,38.260826 162.89242,40.125033 C 158.12955,45.785391 162.28257,44.106811 172.12985,36.39143 C 177.44844,32.224292 182.67144,28.814816 183.73653,28.814816 C 184.80161,28.814816 187.54661,27.504964 189.83652,25.904034 C 194.25574,22.814456 198.50824,21.139901 198.48753,22.497428 C 198.48067,22.946992 195.10567,26.887099 190.98753,31.253222 C 186.86939,35.619346 183.5,39.564104 183.5,40.019351 C 183.5,41.082856 168.79341,55.814816 167.73174,55.814816 C 167.29145,55.814816 166.13375,57.164816 165.15907,58.814816 C 164.18439,60.464816 163.62566,61.814816 163.91743,61.814816 C 165.15382,61.814816 179.64584,55.655591 187.43034,51.821648 C 192.06702,49.538033 198.0484,46.838349 200.72229,45.822351 L 205.58391,43.97508 L 204.94971,46.144948 C 204.24694,48.549405 200.09405,52.509729 194,56.586919 C 191.8,58.058818 188.2,60.672272 186,62.394595 C 183.8,64.116917 179.37277,66.709349 176.1617,68.155554 C 167.28433,72.153761 168.90086,73.374602 182.60097,73.018648 C 194.06638,72.720756 205.81768,74.361788 205.21283,76.176325 C 204.80828,77.389986 196.85799,79.663461 188.25,81.027042 C 184.5375,81.615132 181.5,82.455392 181.5,82.894282 C 181.5,83.333172 183.525,83.995932 186,84.367082 C 188.78027,84.784012 190.5,85.558302 190.5,86.393172 C 190.5,88.777222 187.16275,89.637702 180.11175,89.071722 C 174.50425,88.621602 173.31776,88.777672 173.68351,89.917262 C 173.9302,90.685912 176.12733,91.990102 178.56602,92.815452 C 182.66045,94.201172 190.01097,98.943389 191.73134,101.30912 C 192.13358,101.86225 191.75102,102.84737 190.8812,103.49828 C 190.01139,104.14918 189.56668,105.11368 189.89295,105.6416 C 190.21923,106.16953 189.30993,106.89668 187.87229,107.25751 C 184.85021,108.016 182.49836,110.09069 182.50374,111.99338 C 182.50579,112.72017 183.37363,114.73529 184.43226,116.47144 C 186.10715,119.21824 186.1757,119.86739 184.96032,121.47144 C 182.98394,124.07985 183.17594,125.81481 185.44098,125.81481 C 188.36747,125.81481 188.80694,127.48641 186.33555,129.21744 C 184.19537,130.71648 184.18587,130.81021 185.97381,132.78587 C 187.77856,134.7801 187.76027,134.81507 184.90499,134.83012 C 182.05466,134.84515 178.60125,136.31158 179.52896,137.11296 C 179.78803,137.33675 180.9,138.02253 182,138.63692 C 183.58808,139.52392 183.66479,139.76026 182.37244,139.7844 C 180.09943,139.82687 178.27811,142.19292 179.544,143.45881 C 180.20588,144.12069 179.69429,144.90805 178.02021,145.804 C 176.63409,146.54582 175.5,147.92213 175.5,148.86247 C 175.5,149.82411 174.17066,151.1228 172.46178,151.83064 C 168.92821,153.29429 167.2634,155.81394 168.50379,157.82095 C 169.85582,160.00857 168.72495,160.80976 164.19098,160.87647 C 157.81545,160.97027 147.19214,163.23839 146.73731,164.60289 C 146.5023,165.3079 147.3093,165.85076 148.66667,165.90076 C 150.86682,165.98181 150.84712,166.03286 148.32156,166.79514 C 146.84841,167.23978 144.65474,168.52438 143.44672,169.64982 L 141.25033,171.69607 L 147.12516,171.17407 C 161.37585,169.90784 174.32679,167.5255 182.34452,164.69543 C 191.17489,161.57851 196.62962,159.81481 197.43918,159.81481 C 197.68799,159.81481 195.77846,161.1549 193.19578,162.79279 C 186.4154,167.09278 187.42738,167.36861 195.08305,163.30719 C 201.04237,160.14571 205.5,158.89334 205.5,160.38055 C 205.5,160.69171 205.03417,161.81671 204.46482,162.88055 C 203.70658,164.29733 203.75321,164.81481 204.63913,164.81481 C 205.30435,164.81481 204.75769,165.99976 203.42431,167.44804 L 201,170.08127 L 205.66793,169.58013 C 209.21847,169.19895 210.21731,169.38792 209.84061,170.36958 C 209.56822,171.07941 208.70516,171.90584 207.92268,172.20611 C 204.21195,173.63005 208.39859,176.33434 213.75,175.97018 C 216.67174,175.77135 217.41408,177.50073 215.31012,179.60469 C 213.50244,181.41237 213.50733,183.60365 215.32061,184.29946 C 217.97679,185.31874 214.71722,186.7816 209.75,186.7995 C 207.4125,186.80792 205.5,187.20244 205.5,187.67621 C 205.5,188.14998 197.7375,188.86486 188.25,189.26483 C 178.7625,189.66481 170.79203,190.19764 170.53785,190.44891 C 170.28368,190.70018 170.62499,191.7853 171.29633,192.86029 C 172.76009,195.20415 172.83091,195.19567 167.5,193.31481 C 162.04807,191.39126 158.17262,191.41563 154.33998,193.39756 L 151.27928,194.98031 L 154.86467,197.41664 C 156.83663,198.75663 158.90764,200.70797 159.4669,201.75297 C 160.40125,203.4988 160.13957,203.62774 156.24187,203.34206 C 153.90884,203.17106 150.65,202.72195 149,202.34403 L 146,201.65689 L 148.5,203.71362 C 150.6108,205.45015 150.71837,205.7738 149.19098,205.79257 C 148.12627,205.80566 147.66344,206.27025 148.06609,206.92174 C 148.53176,207.67522 147.83216,207.85241 145.87511,207.47665 C 144.2938,207.17304 141.62267,206.65787 139.93927,206.33184 C 136.86268,205.73597 133.40517,207.98689 133.82126,210.31481 C 133.91957,210.86481 132.9875,211.75902 131.75,212.30194 C 129.24351,213.4016 128.89956,214.81437 130.7,216.61481 C 131.63333,217.54814 131.41893,217.81481 129.73518,217.81481 C 128.54453,217.81481 127.10332,218.6875 126.53248,219.75412 C 125.62991,221.44059 124.71306,221.62636 119.49989,221.17908 C 114.49502,220.74966 113.59856,220.9081 114.07075,222.13862 C 114.38182,222.94926 114.14832,223.91412 113.55185,224.28276 C 112.95539,224.65139 112.75711,225.42182 113.11124,225.99481 C 113.73262,227.00023 107.83775,232.80769 106.19097,232.81246 C 105.74601,232.81375 105.66007,233.26481 105.99999,233.81481 C 106.88685,235.24977 105.13239,235.05165 100.48467,233.192 C 96.719665,231.68555 96.295815,231.68962 94.572915,233.24882 C 93.396675,234.31331 92.910165,235.73166 93.244515,237.12163 C 93.676625,238.91798 93.530345,239.08864 92.436035,238.06481 C 91.701215,237.37731 90.452105,236.81481 89.660235,236.81481 C 88.868375,236.81481 87.673445,236.06669 87.004845,235.15233 C 86.240365,234.10683 85.135265,233.74079 84.027145,234.16602 C 82.459115,234.76773 82.553305,235.06891 84.882535,236.90108 C 86.794315,238.40488 87.468725,239.81662 87.383995,242.13739 C 87.320195,243.88497 87.071095,244.57349 86.830435,243.66744 C 86.589775,242.76138 85.629475,241.74169 84.696435,241.40145 C 83.763395,241.06122 81.920435,240.15261 80.600975,239.38232 C 78.434405,238.11749 77.735325,238.24016 73.386015,240.6483 C 70.737245,242.11488 68.420515,243.98981 68.237715,244.81481 C 67.942295,246.14814 67.842305,246.14814 67.337805,244.81481 z M 50.499995,188.81481 C 50.499995,186.52236 47.989225,186.09752 47.163165,188.2502 C 46.667815,189.54104 47.685065,190.5185 49.749995,190.73586 C 50.162495,190.77928 50.499995,189.91481 50.499995,188.81481 z "
+       id="path2261"
+       sodipodi:nodetypes="cssssssssssssssssssssssssssscccssssssssssssssssssssssssssssscccssssssssssssssssssssssssssssssssssscccssssssscccssssssssssscccsscccsssssssssssssssssssssssssssssccssc" />
+    <g
+       id="g2300"
+       transform="translate(155.79629,-17.407407)" />
+  </g>
+</svg>

=== added file 'Glade/main.glade'
--- Glade/main.glade	1970-01-01 00:00:00 +0000
+++ Glade/main.glade	2010-05-16 16:14:24 +0000
@@ -0,0 +1,644 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Wed Jul 23 00:55:33 2008 -->
+<glade-interface>
+  <requires lib="bonobo"/>
+  <requires lib="gnome"/>
+  <widget class="GnomeApp" id="MainWindow">
+    <property name="width_request">500</property>
+    <property name="height_request">400</property>
+    <property name="visible">True</property>
+    <property name="title" translatable="yes">Rapache</property>
+    <property name="window_position">GTK_WIN_POS_MOUSE</property>
+    <property name="icon">icon_cadsoft_eagle.svg</property>
+    <property name="gravity">GDK_GRAVITY_CENTER</property>
+    <signal name="destroy" handler="on_MainWindow_destroy"/>
+    <child internal-child="dock">
+      <widget class="BonoboDock" id="app1-dock1">
+        <property name="visible">True</property>
+        <child>
+          <widget class="BonoboDockItem" id="dockitem1">
+            <property name="visible">True</property>
+            <child>
+              <widget class="GtkMenuBar" id="menubar1">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkMenuItem" id="menuitem1">
+                    <property name="label" translatable="yes">_File</property>
+                    <property name="use_underline">True</property>
+                    <child>
+                      <widget class="GtkMenu" id="menu1">
+                        <property name="visible">True</property>
+                        <child>
+                          <widget class="GtkImageMenuItem" id="imagemenuitem1">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">gtk-new</property>
+                            <property name="use_underline">True</property>
+                            <property name="use_stock">True</property>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkImageMenuItem" id="imagemenuitem2">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">gtk-open</property>
+                            <property name="use_underline">True</property>
+                            <property name="use_stock">True</property>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkImageMenuItem" id="imagemenuitem3">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">gtk-save</property>
+                            <property name="use_underline">True</property>
+                            <property name="use_stock">True</property>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkImageMenuItem" id="imagemenuitem4">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">gtk-save-as</property>
+                            <property name="use_underline">True</property>
+                            <property name="use_stock">True</property>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
+                            <property name="visible">True</property>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkMenuItem" id="toolsmenu">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">_Tools</property>
+                    <property name="use_underline">True</property>
+                    <child>
+                      <widget class="GtkMenu" id="menu2">
+                        <property name="visible">True</property>
+                        <child>
+                          <widget class="GtkImageMenuItem" id="menuitem2">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">_Reload Apache</property>
+                            <property name="use_underline">True</property>
+                            <signal name="activate" handler="please_restart"/>
+                            <child internal-child="image">
+                              <widget class="GtkImage" id="menu-item-image1">
+                                <property name="stock">gtk-refresh</property>
+                              </widget>
+                            </child>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkSeparatorMenuItem" id="separatormenuitem2">
+                            <property name="visible">True</property>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkImageMenuItem" id="browse_sites_available">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">_Browse sites-available folder as root</property>
+                            <property name="use_underline">True</property>
+                            <signal name="activate" handler="browse_sites_available"/>
+                            <child internal-child="image">
+                              <widget class="GtkImage" id="menu-item-image2">
+                                <property name="stock">gtk-directory</property>
+                              </widget>
+                            </child>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkSeparatorMenuItem" id="separatormenuitem3">
+                            <property name="visible">True</property>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkImageMenuItem" id="menu_quit">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">gtk-quit</property>
+                            <property name="use_underline">True</property>
+                            <property name="use_stock">True</property>
+                            <signal name="activate" handler="on_MainWindow_destroy"/>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkMenuItem" id="menuitem4">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">_Help</property>
+                    <property name="use_underline">True</property>
+                    <child>
+                      <widget class="GtkMenu" id="menu3">
+                        <property name="visible">True</property>
+                        <child>
+                          <widget class="GtkImageMenuItem" id="imagemenuitem10">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">gtk-about</property>
+                            <property name="use_underline">True</property>
+                            <property name="use_stock">True</property>
+                            <signal name="activate" handler="about_clicked"/>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                  </widget>
+                </child>
+              </widget>
+            </child>
+          </widget>
+          <packing>
+            <property name="behavior">BONOBO_DOCK_ITEM_BEH_EXCLUSIVE | BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL | BONOBO_DOCK_ITEM_BEH_LOCKED</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <child>
+              <widget class="GtkHBox" id="restart_apache_notice">
+                <child>
+                  <widget class="GtkVBox" id="vbox5">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkButton" id="restart_apache">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="label" translatable="yes">gtk-refresh</property>
+                        <property name="use_stock">True</property>
+                        <property name="response_id">0</property>
+                        <signal name="clicked" handler="please_restart"/>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="padding">7</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="padding">7</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Applied changes will not take effect until 
+web server is restarted</property>
+                    <property name="justify">GTK_JUSTIFY_CENTER</property>
+                    <property name="wrap">True</property>
+                    <property name="ellipsize">PANGO_ELLIPSIZE_END</property>
+                    <property name="width_chars">0</property>
+                  </widget>
+                  <packing>
+                    <property name="padding">4</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkVBox" id="vbox6">
+                    <property name="visible">True</property>
+                    <property name="homogeneous">True</property>
+                    <child>
+                      <widget class="GtkButton" id="button_hide_warning">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="relief">GTK_RELIEF_NONE</property>
+                        <property name="focus_on_click">False</property>
+                        <property name="response_id">0</property>
+                        <signal name="clicked" handler="on_button_hide_warning_clicked"/>
+                        <child>
+                          <widget class="GtkImage" id="image2">
+                            <property name="visible">True</property>
+                            <property name="stock">gtk-close</property>
+                          </widget>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="padding">8</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkNotebook" id="notebook">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <child>
+                  <widget class="GtkVBox" id="vbox4">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkHBox" id="hbox4">
+                        <property name="visible">True</property>
+                        <child>
+                          <widget class="GtkToolbar" id="toolbar1">
+                            <property name="visible">True</property>
+                            <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
+                            <child>
+                              <widget class="GtkToolButton" id="new">
+                                <property name="visible">True</property>
+                                <property name="is_important">True</property>
+                                <property name="use_underline">True</property>
+                                <property name="stock_id">gtk-new</property>
+                                <signal name="clicked" handler="new_button_clicked"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkToolButton" id="edit_button">
+                                <property name="visible">True</property>
+                                <property name="sensitive">False</property>
+                                <property name="is_important">True</property>
+                                <property name="use_underline">True</property>
+                                <property name="stock_id">gtk-edit</property>
+                                <signal name="clicked" handler="edit_button_clicked"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkToolButton" id="delete_button">
+                                <property name="visible">True</property>
+                                <property name="sensitive">False</property>
+                                <property name="is_important">True</property>
+                                <property name="stock_id">gtk-delete</property>
+                                <signal name="clicked" handler="on_delete"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkSeparatorToolItem" id="toolbutton1">
+                                <property name="visible">True</property>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="homogeneous">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkToolButton" id="browse_button">
+                                <property name="visible">True</property>
+                                <property name="sensitive">False</property>
+                                <property name="is_important">True</property>
+                                <property name="label" translatable="yes">Browse</property>
+                                <property name="stock_id">gtk-open</property>
+                                <signal name="clicked" handler="browse_button_clicked"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkToolButton" id="surf_this_button">
+                                <property name="visible">True</property>
+                                <property name="sensitive">False</property>
+                                <property name="is_important">True</property>
+                                <property name="label" translatable="yes">Open Site</property>
+                                <property name="icon_name">applications-internet</property>
+                                <signal name="clicked" handler="surf_this_button_clicked"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                              </packing>
+                            </child>
+                          </widget>
+                        </child>
+                        <child>
+                          <placeholder/>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkScrolledWindow" id="vhosts_scroll_box">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                        <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                        <child>
+                          <widget class="GtkViewport" id="viewport1">
+                            <property name="visible">True</property>
+                            <property name="resize_mode">GTK_RESIZE_QUEUE</property>
+                            <property name="shadow_type">GTK_SHADOW_NONE</property>
+                            <child>
+                              <widget class="GtkVBox" id="vhost_container">
+                                <property name="visible">True</property>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                              </widget>
+                            </child>
+                          </widget>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkHBox" id="hbox1">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkImage" id="image3">
+                        <property name="visible">True</property>
+                        <property name="icon_name">applications-internet</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label2">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Virtual Hosts</property>
+                      </widget>
+                      <packing>
+                        <property name="padding">5</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="type">tab</property>
+                    <property name="tab_fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkVBox" id="vbox3">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkHBox" id="hbox5">
+                        <property name="visible">True</property>
+                        <child>
+                          <widget class="GtkToolbar" id="toolbar2">
+                            <property name="visible">True</property>
+                            <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
+                            <child>
+                              <widget class="GtkToolButton" id="edit_module_button">
+                                <property name="visible">True</property>
+                                <property name="sensitive">False</property>
+                                <property name="is_important">True</property>
+                                <property name="use_underline">True</property>
+                                <property name="stock_id">gtk-edit</property>
+                                <signal name="clicked" handler="edit_module_button_clicked"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                              </packing>
+                            </child>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkToolbar" id="toolbar3">
+                            <property name="visible">True</property>
+                            <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
+                            <property name="show_arrow">False</property>
+                            <child>
+                              <widget class="GtkToolButton" id="open_doc_button">
+                                <property name="visible">True</property>
+                                <property name="sensitive">False</property>
+                                <property name="is_important">True</property>
+                                <property name="label" translatable="yes">Module Documentation</property>
+                                <property name="stock_id">gtk-help</property>
+                                <signal name="clicked" handler="open_doc_button_clicked"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                              </packing>
+                            </child>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="pack_type">GTK_PACK_END</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkScrolledWindow" id="modules_scroll_box">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                        <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                        <child>
+                          <widget class="GtkViewport" id="viewport2">
+                            <property name="visible">True</property>
+                            <property name="resize_mode">GTK_RESIZE_QUEUE</property>
+                            <property name="shadow_type">GTK_SHADOW_NONE</property>
+                            <child>
+                              <widget class="GtkVBox" id="modules_container">
+                                <property name="visible">True</property>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                              </widget>
+                            </child>
+                          </widget>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkHBox" id="hbox2">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkImage" id="image4">
+                        <property name="visible">True</property>
+                        <property name="pixbuf">modules.png</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label3">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Modules List</property>
+                      </widget>
+                      <packing>
+                        <property name="padding">5</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="type">tab</property>
+                    <property name="position">1</property>
+                    <property name="tab_fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkScrolledWindow" id="scrolledwindow1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <child>
+                      <widget class="GtkViewport" id="viewport3">
+                        <property name="visible">True</property>
+                        <property name="resize_mode">GTK_RESIZE_QUEUE</property>
+                        <child>
+                          <widget class="GtkVBox" id="problems_area">
+                            <property name="visible">True</property>
+                            <child>
+                              <widget class="GtkHBox" id="unnormalized_notice">
+                                <property name="visible">True</property>
+                                <child>
+                                  <widget class="GtkImage" id="image1">
+                                    <property name="visible">True</property>
+                                    <property name="xpad">10</property>
+                                    <property name="stock">gtk-dialog-warning</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <widget class="GtkVBox" id="vbox2">
+                                    <property name="visible">True</property>
+                                    <child>
+                                      <widget class="GtkLabel" id="label5">
+                                        <property name="visible">True</property>
+                                        <property name="yalign">0</property>
+                                        <property name="ypad">5</property>
+                                        <property name="label" translatable="yes">&lt;small&gt;The following  Virtual Hosts are only present inside /etc/apache/sites-enabled. You have to normalize them in order to be able to manage them.&lt;/small&gt;</property>
+                                        <property name="use_markup">True</property>
+                                        <property name="wrap">True</property>
+                                      </widget>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkButton" id="fix_vhosts">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">True</property>
+                                        <property name="label" translatable="yes">gtk-execute</property>
+                                        <property name="use_stock">True</property>
+                                        <property name="yalign">0</property>
+                                        <property name="response_id">0</property>
+                                        <signal name="clicked" handler="fix_vhosts_clicked"/>
+                                      </widget>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">False</property>
+                                        <property name="padding">5</property>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                  </widget>
+                                  <packing>
+                                    <property name="fill">False</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <placeholder/>
+                            </child>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkHBox" id="hbox3">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkImage" id="image5">
+                        <property name="visible">True</property>
+                        <property name="stock">gtk-dialog-warning</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label6">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Problems</property>
+                      </widget>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="type">tab</property>
+                    <property name="position">2</property>
+                    <property name="tab_fill">False</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+        </child>
+      </widget>
+      <packing>
+        <property name="expand">True</property>
+        <property name="fill">True</property>
+      </packing>
+    </child>
+    <child internal-child="appbar">
+      <widget class="GnomeAppBar" id="app1-appbar1">
+        <property name="visible">True</property>
+        <property name="spacing">4</property>
+        <property name="has_progress">True</property>
+        <property name="has_status">True</property>
+      </widget>
+      <packing>
+        <property name="position">1</property>
+      </packing>
+    </child>
+  </widget>
+</glade-interface>

=== added file 'Glade/modules.png'
Binary files Glade/modules.png	1970-01-01 00:00:00 +0000 and Glade/modules.png	2010-05-16 16:14:24 +0000 differ
=== added file 'Glade/modules.xml'
--- Glade/modules.xml	1970-01-01 00:00:00 +0000
+++ Glade/modules.xml	2010-05-16 16:14:24 +0000
@@ -0,0 +1,211 @@
+<modules>
+	<module name='mod_access'>Provides access control based on client hostname, IP address, or other characteristics of the client request.</module>
+	<module name='mod_actions'>This module provides for executing CGI scripts based on media type or request method.</module>
+	<module name='mod_alias'>Provides for mapping different parts of the host filesystem in the document tree and for URL redirection</module>
+	<module name='mod_asis'>Sends files that contain their own HTTP headers</module>
+	<module name='mod_auth'>User authentication using text files</module>
+	<module name='mod_auth_anon'>Allows "anonymous" user access to authenticated areas</module>
+	<module name='mod_auth_dbm'>Provides for user authentication using DBM files</module>
+	<module name='mod_auth_digest'>User authentication using MD5 Digest Authentication.</module>
+	<module name='mod_auth_ldap'>Allows an LDAP directory to be used to store the database for HTTP Basic authentication.</module>
+	<module name='mod_autoindex'>Generates directory indexes, automatically, similar to the Unix ls command or the Win32 dir shell command</module>
+	<module name='mod_cache'>Content cache keyed to URIs.</module>
+	<module name='mod_cern_meta'>CERN httpd metafile semantics</module>
+	<module name='mod_cgi'>Execution of CGI scripts</module>
+	<module name='mod_cgid'>Execution of CGI scripts using an external CGI daemon</module>
+	<module name='mod_charset_lite'>Specify character set translation or recoding</module>
+	<module name='mod_dav'>Distributed Authoring and Versioning (WebDAV) functionality</module>
+	<module name='mod_dav_fs'>filesystem provider for mod_dav</module>
+	<module name='mod_deflate'>Compress content before it is delivered to the client</module>
+	<module name='mod_dir'>Provides for "trailing slash" redirects and serving directory index files</module>
+	<module name='mod_disk_cache'>Content cache storage manager keyed to URIs</module>
+	<module name='mod_dumpio'>Dumps all I/O to error log as desired.</module>
+	<module name='mod_echo'>A simple echo server to illustrate protocol modules</module>
+	<module name='mod_env'>Modifies the environment which is passed to CGI scripts and SSI pages</module>
+	<module name='mod_example'>Illustrates the Apache module API</module>
+	<module name='mod_expires'>Generation of Expires and Cache-Control HTTP headers according to user-specified criteria</module>
+	<module name='mod_ext_filter'>Pass the response body through an external program before delivery to the client</module>
+	<module name='mod_file_cache'>Caches a static list of files in memory</module>
+	<module name='mod_headers'>Customization of HTTP request and response headers</module>
+	<module name='mod_imap'>Server-side imagemap processing</module>
+	<module name='mod_include'>Server-parsed html documents (Server Side Includes)</module>
+	<module name='mod_info'>Provides a comprehensive overview of the server configuration</module>
+	<module name='mod_isapi'>ISAPI Extensions within Apache for Windows</module>
+	<module name='mod_ldap'>LDAP connection pooling and result caching services for use by other LDAP modules</module>
+	<module name='mod_log_config'>Logging of the requests made to the server</module>
+	<module name='mod_log_forensic'>Forensic Logging of the requests made to the server</module>
+	<module name='mod_logio'>Logging of input and output bytes per request</module>
+	<module name='mod_mem_cache'>Content cache keyed to URIs</module>
+	<module name='mod_mime'>Associates the requested filename's extensions with the file's behavior (handlers and filters) and content (mime-type, language, character set and encoding)</module>
+	<module name='mod_mime_magic'>Determines the MIME type of a file by looking at a few bytes of its contents</module>
+	<module name='mod_negotiation'>Provides for content negotiation</module>
+	<module name='mod_nw_ssl'>Enable SSL encryption for NetWare</module>
+	<module name='mod_proxy'>HTTP/1.1 proxy/gateway server</module>
+	<module name='mod_proxy_connect'>mod_proxy extension for CONNECT request handling</module>
+	<module name='mod_proxy_ftp'>FTP support module for mod_proxy</module>
+	<module name='mod_proxy_http'>HTTP support module for mod_proxy</module>
+	<module name='mod_rewrite'>Provides a rule-based rewriting engine to rewrite requested URLs on the fly</module>
+	<module name='mod_setenvif'>Allows the setting of environment variables based on characteristics of the request</module>
+	<module name='mod_so'>Loading of executable code and modules into the server at start-up or restart time</module>
+	<module name='mod_speling'>Attempts to correct mistaken URLs that users might have entered by ignoring capitalization and by allowing up to one misspelling</module>
+	<module name='mod_ssl'>Strong cryptography using the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols</module>
+	<module name='mod_status'>Provides information on server activity and performance</module>
+	<module name='mod_suexec'>Allows CGI scripts to run as a specified user and Group</module>
+	<module name='mod_unique_id'>Provides an environment variable with a unique identifier for each request</module>
+	<module name='mod_userdir'>User-specific directories</module>
+	<module name='mod_usertrack'>Clickstream logging of user activity on a site </module>
+	<module name='mod_version'>Version dependent configuration</module>
+	<module name='mod_vhost_alias'>Provides for dynamically configured mass virtual hosting </module>
+
+
+	<module name='anti-contraband'>anti-spam module</module>
+	<module name='Apache Proxy FastCGI'>proxy scheme module for FastCGI protocol...</module>
+	<module name='Auth MemCookie'>Apache Cookie Authentification Module</module>
+	<module name='Bandwidth Module'>Bandwidth and Connection control per Virtual Host or Directory</module>
+	<module name='CPPSERV'>application server/servlet container with apache module that provide Java Servlet-like API and C++ Servlet Pages implementation to C++ programmers</module>
+	<module name='DACS'>A light-weight, general-purpose authentication, authorization, and single sign-on system</module>
+	<module name='gbap-pool'>stl allocator for apache memory pools</module>
+	<module name='LDAP auth module'>HTTP basic authentication with LDAP</module>
+	<module name='mod-apache-snmp'>SNMP module for Apache</module>
+	<module name='mod-captcha'>mod-captcha is an Apache 2 module to prevent web sites from maliciosus software access. Developed in UNPSJB.</module>
+	<module name='mod-ipenv'>set/unset environment variables based on client IP addresses or client hostnames.</module>
+	<module name='mod-log-spread2'>rewrite from scratch to allow logging to use reliable messaging framework - spread</module>
+	<module name='mod-wiki'>mod-wiki is a wiki as a module</module>
+	<module name='modXLdapAuth'>X509 certificate authentication and LDAP authorization module</module>
+	<module name='mod_accessibility'>filter for server or proxy to improve accessibility of web contents on-the-fly</module>
+	<module name='mod_access_dnsbl     '>Access control based on DNSBL blacklists and whitelists.</module>
+	<module name='mod_acronym'>Sample filter module for Acronyms</module>
+	<module name='mod_activex_filter'>Enable ActiveX filtering for Apache proxy</module>
+	<module name='mod_antispam'>by using this module, you can control referer spam accesses</module>
+	<module name='mod_athena'>load balancer plugin for mod_proxy</module>
+	<module name='mod_authnz_external'>Authentication provider using user provided scripts - secure authentication from Unix passwd file</module>
+	<module name='mod_authnz_ibmdb2'>mod_authnz_ibmdb2 is an Apache authentication module using IBM DB2 as database for storing user and group information.</module>
+	<module name='mod_authnz_sasl'>SASL socket based autnz module</module>
+	<module name='mod_authn_dbi'>For Apache 2.1+ that uses libdbi to provide access to database backends, including MySQL, PgSQL, Oracle, and others</module>
+	<module name='mod_authn_sasl'>Cyrus SASL authentication module</module>
+	<module name='mod_authz_unixgroup'>Check access control based on membership in Unix groups</module>
+	<module name='mod_auth_cookie_dbm'>Session authentication/expiration using (cryptographically strong) cookies. Cookie-to-username mapping with DBM database.</module>
+	<module name='mod_auth_form'> Form-based, authorization module using MySQL and session management.</module>
+	<module name='mod_auth_imap'>imap authentication module</module>
+	<module name='mod_auth_msfix'>When MS XP Clients connect to WebDAV they may have a problem sending the user's name to Apache. This mod can fix the user's name</module>
+	<module name='mod_auth_mysql'>MySQL-based authentication module with VirtualHost support (you need only one database for all VirtualHosts), now with SSL Support for the Connection to the MySQL-Server</module>
+	<module name='mod_auth_openpgp'>OpenPGP Signature Verification for signed HTTP requests (see Enigform, mod_access).</module>
+	<module name='mod_auth_oracle'>Authentication module for Apache 2.0 -> Oracle8/8i/9i</module>
+	<module name='mod_auth_pam'>Add PAM authentication</module>
+	<module name='mod_auth_pamacea'>Login form based auth module using PAM</module>
+	<module name='mod_auth_pamport'>Provides PAM authentication. Module uses pamport to provide a flexible interface to PAM services.</module>
+	<module name='mod_auth_phpbb'>auth by phpbb user and group</module>
+	<module name='mod_auth_sim'>Authentication Session ID Management using MySQL and cookies.</module>
+	<module name='mod_auth_timeout'>Idle timeout for basic auth/ldap auth.</module>
+	<module name='mod_auth_token'>Token-based authentication similar to mod_secdownload in LIGHTTPD. Have your script generate a token and let Apache handle the file transfer without having to pipe it through a script for security.</module>
+	<module name='mod_auth_useragent2'>Unsafe authentication for the Apache web server using the User-Agent</module>
+	<module name='mod_auth_user_dir'>User directory based authentication</module>
+	<module name='mod_auth_xradius'>RADIUS Authentication Module</module>
+	<module name='mod_bt'>BitTorrent tracker implementation with PHP and Perl language hooks</module>
+	<module name='mod_but V2.9 (Entry Server - SSO)'>MOD_BUT is a powerful entry server, including SSO, backend session hiding, shared memory session store, service authorization, authentication strengths and levels, login and logout features.</module>
+	<module name='mod_bwshare'>Bandwidth throttling and monitoring per client IP address.</module>
+	<module name='mod_caldav'>CalDAV RFC4791 module</module>
+	<module name='mod_cband'>A virtual host bandwidth-limiting module provided to solve the problem of limiting virtualhosts and users bandwidth usage</module>
+	<module name='mod_cbroker'>HTTP/CORBA gateway</module>
+	<module name='mod_cfg_ldap'>Module that provides Vhost lookups via LDAP</module>
+	<module name='mod_cguard'>simple and flexible connection limiter</module>
+	<module name='mod_clamav'>Virus Scanning module for Apache2</module>
+	<module name='mod_concat'>concatenate multiple files together in one URL request, similar to what perlbal does</module>
+	<module name='mod_countm'>Counter returning count via jpeg or png image.</module>
+	<module name='mod_cplusplus'>A C++ wrapper around apache-2.0</module>
+	<module name='mod_crowd'>CROWD is a web-based single sign-on (SSO) tool for provisioning and identity management developed by Atlassian. This module allows for Basic authentication calls from apache over to CROWD SSO.</module>
+	<module name='mod_csv'>Publishes CSV/spreadsheet data to the Web</module>
+	<module name='mod_dav_acl'>RFC3744 (Access Control Rights)</module>
+	<module name='mod_dav_svn'>Filesystem provider module distributed with Sub</module>
+	<module name='mod_daytime'>RFC-867-compliant Daytime service</module>
+	<module name='mod_dbd_mysql'>DBD Driver module for MySQL.   To replace mod_mysql_pool</module>
+	<module name='mod_dbd_pgsql'>DBD Driver module for PostgreSQL.  To replace mod_pg_pool</module>
+	<module name='mod_debug'>Gives an html-header with request-information</module>
+	<module name='mod_diagnostics.c'>Debug tool for filters; aid to tracing buckets</module>
+	<module name='mod_domaintree'>Mass virtual hosting module mapping host names to a directory tree</module>
+	<module name='mod_dsp'>DSP - Davor Server Pages: PL/SQL Server Scripting + ORACLE AUTHNZ</module>
+	<module name='mod_estraier'>mod_estraier is an apache module that registers web pages processed by the apache and search from them using the node API of Hyper Estraier.</module>
+	<module name='mod_example_ipc     '>Sample code demonstrating shared memory and mutex usage in modules</module>
+	<module name='mod_expat'>Filter module to turn XML into SAX buckets. This module has been replaced by mod_xml2 and will be no longer maintained.</module>
+	<module name='mod_fcgid'>Apache2 module for FastCGI protocol</module>
+	<module name='mod_footer'>add footer to certain pages with certain vars</module>
+	<module name='mod_ftpd'>FTP Protocol module</module>
+	<module name='mod_globule'>A module for server-to-server document replication. Clients are automatically redirected to one of the replicas.</module>
+	<module name='mod_gridsite'>Grid authentication (GSI) and authorization (GACL, VOMS) in an Apache module</module>
+	<module name='mod_highlight'>Syntax Highlighting in an Apache 2.0 Output Filter</module>
+	<module name='mod_i18n'>Implements the i18n namespace to provide gettext translation as an output filter.</module>
+	<module name='mod_idcheck'>Cookie based web authentication and single sign on system designed for largish</module>
+	<module name='mod_ifier'>Apache2 request filtering and rejection</module>
+	<module name='mod_injection'>Inject text after the HTML body tag.</module>
+	<module name='mod_ip_count'>limit the number of requests to your server farm by incoming IP</module>
+	<module name='mod_itp'>Implements  simputer  transfer protocol : ITP</module>
+	<module name='mod_line_edit'>General-purpose fast text filter</module>
+	<module name='mod_log50x'>Log error 500 - 509 to logfiles</module>
+	<module name='mod_log_access'>customised, automatically rotated logs</module>
+	<module name='mod_log_firstbyte'>New in performance testing! Enables you to log the time between the request being read and the first byte served.</module>
+	<module name='mod_log_mysql'>Use one or more MySQL databases to log requests</module>
+	<module name='mod_lua'>Module support LUA Script or html embbed LUA</module>
+	<module name='mod_memcached_cache'>mod_cache provider module for memcached storage</module>
+	<module name='mod_mldap'></module>
+	<module name='mod_mono'>module ASP.NET for Apache</module>
+	<module name='mod_mono'>Runs ASP.NET pages on Unix with Apache and Mono</module>
+	<module name='mod_murka'>xml/xsl based web publishing environment</module>
+	<module name='mod_oai'>Open Archives Initiative Protocol for Metadata Harvesting (OAI-PMH) support</module>
+	<module name='mod_pgheader'>Replaces body tags with headers/footers</module>
+	<module name='mod_prolog'>Embedded prolog interpreter</module>
+	<module name='mod_proxy_html'>Fixup HTML Links for Reverse Proxy/Mirror</module>
+	<module name='mod_proxy_xml'>Fixup Links in XML doc types (eg WML) for Reverse Proxy/Mirror</module>
+	<module name='mod_publisher'>Universal markup processing filter</module>
+	<module name='mod_python'>Apache/Python Integration</module>
+	<module name='mod_qos'>Quality of service module implementing control mechanisms that can provide different priority to different requests.</module>
+	<module name='mod_replace_regex'>replace text with regex pattern</module>
+	<module name='mod_ruid'>based on mod_suid2 only for linux</module>
+	<module name='mod_sasl_auth'>Module to allow authentication with sasl</module>
+	<module name='mod_schema'>w3c/xml schema validator</module>
+	<module name='mod_scheme'>Apache 2 module for Scheme language</module>
+	<module name='mod_sesehe SEcure SErver HEader'>Modify or remove 'Server: ' HTTP response header. More on :  Module homepage</module>
+	<module name='mod_setenvauthpw'>This module acquires a password from a request_rec structure body and incorporates it in an environment variable An environment.  An environment variable name is REMOTE_PASSWORD.</module>
+	<module name='mod_spin'>Template engine, C API support via shared libraries, database connection pooling, persistent session/application data tracking</module>
+	<module name='mod_sqil'>A RDBMS => XML mapper</module>
+	<module name='mod_sql'>XML Namespace module to add SQL ops/queries</module>
+	<module name='mod_ssi_func'>extensions to mod_include for math functions, random number generation, one step value pair variable setting and flastmod vars</module>
+	<module name='mod_ssl_error'>X.509 certificate validation error trapping (SSL)</module>
+	<module name='mod_suexec_helper'>Adds UserId and GroupId directives to apache which are passed as arguments to suexec when starting CGI scripts.</module>
+	<module name='mod_suid2'>Suexec module for Apache2. it support chroot.</module>
+	<module name='mod_swf2html'>Provides `glue between Apache 2 and Macromedia Flash Seach Engine SDK</module>
+	<module name='mod_tee'>Clone a response as it is sent to the client</module>
+	<module name='mod_tidy     '>mod_tidy is a TidyLib based DSO module for the Apache HTTP Server</module>
+	<module name='mod_traf_thief'>This simple module allows you to redirect percent of traffic to your url.</module>
+	<module name='mod_txt'>Display plain text files as prettified HTML with header+footer in the manner of directory indexes</module>
+	<module name='mod_upload'>Input filter for file uploads (multipart/form-data)</module>
+	<module name='mod_uploader'>High performance, low burdened apache-moduled uploader</module>
+	<module name='mod_usertild'>UserTild Module</module>
+	<module name='mod_valet_admin'>Site Valet Configuration and Admin Functions</module>
+	<module name='mod_valet_audit'>Module for browser-based accessibility audit/reporting.</module>
+	<module name='mod_valet_publish'>XML/XSLT publishing system for reports (POST, PUT, GET + XSLT)</module>
+	<module name='mod_valet_report'>Site Valet Query and Browse Functions</module>
+	<module name='mod_valet_sql'>Manage a dynamic pool of SQL connections</module>
+	<module name='mod_valet_utils'>Utility module: Form handling and templatised report generation</module>
+	<module name='mod_validator'>Markup Validation (HTML, XML, SGML) module</module>
+	<module name='mod_vd'>A virtual domain to directory mapper. Fast variant of mod_vhost_alias.</module>
+	<module name='mod_vhost ldap/pgsql/mysql module'>mod_vhost based on ldap/pgsql/mysql backend</module>
+	<module name='mod_vhost_ldap'>Virtual Hosting from ldap built on top of mod_ldap (caching included). Module is now considered feature completed.</module>
+	<module name='mod_vhost_mysql2'>Provides dynamically configured Virtual Hosting in Apache2.</module>
+	<module name='mod_vhost_mysql2'>Provides dynamically configured Virtual Hosting in Apache2. With in Alias fabian@xxxxxxxxxx</module>
+	<module name='mod_vhs'>Virtual Hosting Module that can get data from LDAP, MySQL, PAM, ... This module sets correctly the DOCUMENT_ROOT internal apache</module>
+	<module name='mod_websh'>Tcl extension for rapid web application development</module>
+	<module name='mod_wxjs'>Module for using JavaScript / wxWidgets as server-side language.</module>
+	<module name='mod_xcap'>XCAP (RFC4825)</module>
+	<module name='mod_xhtml'>Namespace module for XHTML (ensure W3C Appendix C) and SSI implementation</module>
+	<module name='mod_xi'>partial XInclude implementation</module>
+	<module name='mod_xml'>[obsolete] API/Framework for XML Applications with Apache 2.0</module>
+	<module name='mod_xml2'>This module provides a filter to turn XML/HTML into a stream of sax buckets.</module>
+	<module name='mod_xmlns'>Adds XML namespace support to publishing with Apache</module>
+	<module name='mod_xsendfile   '>Serves alternative content by processing X-SENDFILE headers.</module>
+	<module name='mod_xslt'>A Filter to parse xml with an xsl</module>
+	<module name='mod_zrkadlo'>A database-backed mirror redirector</module>
+	<module name='mon_mono'>Running .Net framework in cross-platform</module>
+	<module name='vdbh_SQLite'>virtual host from SQLite3</module>
+	<module name='Vhost Limit Module'>Allow to specify the max clients, per virtual host</module>
+	<module name='xmlns_esi'>Parser for Edge Side Includes</module>
+</modules>

=== added file 'Glade/old_edit_vhost.glade'
--- Glade/old_edit_vhost.glade	1970-01-01 00:00:00 +0000
+++ Glade/old_edit_vhost.glade	2010-05-16 16:14:24 +0000
@@ -0,0 +1,317 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Mon Jun 23 01:58:11 2008 -->
+<glade-interface>
+  <widget class="GtkWindow" id="vhost_edit_window">
+    <property name="visible">True</property>
+    <property name="border_width">10</property>
+    <property name="title" translatable="yes">New Virtual Host</property>
+    <property name="modal">True</property>
+    <property name="window_position">GTK_WIN_POS_CENTER</property>
+    <signal name="destroy" handler="quit"/>
+    <child>
+      <widget class="GtkNotebook" id="notebook">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <child>
+          <widget class="GtkVPaned" id="vpaned1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <child>
+              <widget class="GtkHBox" id="message_container">
+                <child>
+                  <widget class="GtkImage" id="image1">
+                    <property name="visible">True</property>
+                    <property name="stock">gtk-dialog-error</property>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="message_text">
+                    <property name="visible">True</property>
+                    <property name="ypad">10</property>
+                    <property name="label" translatable="yes">Error: Virtual Host creation aborted.</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="resize">False</property>
+                <property name="shrink">True</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkTable" id="table1">
+                <property name="visible">True</property>
+                <property name="n_rows">5</property>
+                <property name="n_columns">2</property>
+                <property name="column_spacing">10</property>
+                <property name="row_spacing">10</property>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <widget class="GtkVBox" id="vbox1">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkCheckButton" id="set_custom_folder">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="label" translatable="yes">Let me choose custom _folder</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
+                        <signal name="toggled" handler="custom_folder_toggled"/>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkFileChooserButton" id="custom_folder">
+                        <property name="title" translatable="yes">Select A Folder</property>
+                      </widget>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkEntry" id="default_folder">
+                        <property name="visible">True</property>
+                        <property name="sensitive">False</property>
+                        <property name="can_focus">True</property>
+                        <property name="editable">False</property>
+                        <property name="truncate_multiline">True</property>
+                      </widget>
+                      <packing>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="create_hosts_entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Add an entry to /etc/_hosts</property>
+                    <property name="use_underline">True</property>
+                    <property name="response_id">0</property>
+                    <property name="active">True</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="create_hosts_label">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">If you do not have a registered 
+domain you will need an entry in 
+your &lt;b&gt;/etc/hosts&lt;/b&gt; file.</property>
+                    <property name="use_markup">True</property>
+                    <property name="wrap">True</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label5">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Target folder:</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkButton" id="ok_button">
+                    <property name="visible">True</property>
+                    <property name="sensitive">False</property>
+                    <property name="can_focus">True</property>
+                    <property name="is_focus">True</property>
+                    <property name="can_default">True</property>
+                    <property name="has_default">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="label" translatable="yes">gtk-save</property>
+                    <property name="use_stock">True</property>
+                    <property name="response_id">0</property>
+                    <signal name="clicked" handler="on_ok"/>
+                    <accelerator key="Return" modifiers="" signal="clicked"/>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">4</property>
+                    <property name="bottom_attach">5</property>
+                    <property name="x_options">GTK_EXPAND</property>
+                    <property name="y_options">GTK_EXPAND</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkButton" id="cancel_button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="label" translatable="yes">gtk-cancel</property>
+                    <property name="use_stock">True</property>
+                    <property name="response_id">0</property>
+                    <signal name="clicked" handler="on_cancel"/>
+                    <accelerator key="Escape" modifiers="" signal="activate"/>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">4</property>
+                    <property name="bottom_attach">5</property>
+                    <property name="x_options">GTK_EXPAND</property>
+                    <property name="y_options">GTK_EXPAND</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label6">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Domain name:
+(no http:// or www)</property>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="has_www">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Create _www</property>
+                    <property name="use_underline">True</property>
+                    <property name="response_id">0</property>
+                    <property name="active">True</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkEntry" id="domain_name">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="has_focus">True</property>
+                    <property name="is_focus">True</property>
+                    <signal name="delete_from_cursor" handler="domain_name_updated"/>
+                    <signal name="changed" handler="domain_name_updated"/>
+                    <signal name="delete_text" handler="domain_name_updated"/>
+                    <signal name="insert_text" handler="domain_name_updated"/>
+                    <signal name="activate" handler="domain_name_updated"/>
+                    <signal name="paste_clipboard" handler="domain_name_updated"/>
+                    <signal name="copy_clipboard" handler="domain_name_updated"/>
+                    <signal name="cut_clipboard" handler="domain_name_updated"/>
+                    <signal name="insert_at_cursor" handler="domain_name_updated"/>
+                    <signal name="backspace" handler="domain_name_updated"/>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="resize">True</property>
+                <property name="shrink">True</property>
+              </packing>
+            </child>
+          </widget>
+        </child>
+        <child>
+          <widget class="GtkHBox" id="hbox2">
+            <property name="visible">True</property>
+            <child>
+              <widget class="GtkImage" id="image3">
+                <property name="visible">True</property>
+                <property name="stock">gtk-properties</property>
+                <property name="icon_size">1</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Details</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="type">tab</property>
+            <property name="tab_fill">False</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkScrolledWindow" id="scrolledwindow1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+            <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+            <child>
+              <widget class="GtkTextView" id="vhost_source">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="editable">False</property>
+                <property name="indent">1</property>
+                <property name="text" translatable="yes">Once created, the vhost definition will be visible here</property>
+              </widget>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkHBox" id="hbox1">
+            <property name="visible">True</property>
+            <child>
+              <widget class="GtkImage" id="image2">
+                <property name="visible">True</property>
+                <property name="stock">gtk-file</property>
+                <property name="icon_size">1</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label2">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Virtual Host definition</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="type">tab</property>
+            <property name="position">1</property>
+            <property name="tab_fill">False</property>
+          </packing>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+          <packing>
+            <property name="type">tab</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>

=== added file 'Glade/warning_dialog.glade'
--- Glade/warning_dialog.glade	1970-01-01 00:00:00 +0000
+++ Glade/warning_dialog.glade	2010-05-16 16:14:24 +0000
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Sat Jun 28 18:51:41 2008 -->
+<glade-interface>
+  <widget class="GtkWindow" id="window1">
+    <property name="visible">True</property>
+    <property name="border_width">10</property>
+    <property name="title" translatable="yes">Rapache Warning</property>
+    <property name="window_position">GTK_WIN_POS_CENTER</property>
+    <signal name="destroy" handler="quit"/>
+    <child>
+      <widget class="GtkVBox" id="vbox1">
+        <property name="visible">True</property>
+        <child>
+          <widget class="GtkLabel" id="label1">
+            <property name="visible">True</property>
+            <property name="label" translatable="yes">label</property>
+          </widget>
+        </child>
+        <child>
+          <widget class="GtkHButtonBox" id="hbuttonbox1">
+            <property name="visible">True</property>
+            <child>
+              <widget class="GtkButton" id="okbutton1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+                <signal name="clicked" handler="on_ok"/>
+              </widget>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>
+

=== added directory 'RapacheCore'
=== renamed directory 'RapacheCore' => 'RapacheCore.moved'
=== added file 'RapacheCore/ApacheConf.py'
--- RapacheCore/ApacheConf.py	1970-01-01 00:00:00 +0000
+++ RapacheCore/ApacheConf.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,344 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+ASSUMPTIONS
+    - when multiple directive with the same name are encountered
+      the last one wins.
+    - directives without options could be ok.
+        - ServerAlias without any option works
+        
+GOALS:
+    - change as little as possible when updating to reduce the risk 
+      of breaking something
+      
+TODO:
+    - search for subsections and limit editing to a certain subsection
+    - insert directive where it doesn't exist
+    - remove a directive when it becomes empty (without options)
+    - verify apache handling of case for directives
+"""
+
+import re
+from RapacheCore.Observer import PollyObserver
+from RapacheCore.Observer import Observable
+
+class Parser (Observable):
+    filename = None
+    content = None
+    parser = None
+    
+    def __init__ (self, *args, **kwargs):
+        super (Parser, self).__init__ (*args, **kwargs)
+        self.parser = LineParser()
+        self.apply_observing_policy()
+    
+    def apply_observing_policy(self):
+        """register the object with the observer"""
+        self.observer = PollyObserver()
+        self.observer.register(self)
+        
+    def load(self, filename ):
+        self.filename = filename
+        file = open ( filename, 'r' )
+        self.content = file.readlines()
+        file.close()
+        return self.content
+    
+    def get_value(self, name):
+        line = self.get_directive(name)    
+        if line == None: return None
+        return self.parser.get_value(line)
+    def set_value (self, name, value):
+        idx = self._get_last_directive_idx(name)
+        if idx == None:
+            idx = self._last_line_idx()
+            line = name+"\t"+self.parser.value_escape( value )+"\n"
+            self.insert_line( self._last_line_idx(), line )
+        else:
+            line = self.get_line( idx )
+            line = self.parser.change_value(line, value)
+            self.set_line( idx, line )
+    def remove_value(self, name):
+        idx = self._get_last_directive_idx(name)
+        print "removing line:",idx
+        if idx: 
+            self.remove_line(idx)
+            return True
+        return False
+    def get_directive(self, name):
+        idx = self._get_last_directive_idx(name)
+        if ( idx == None ): return None
+        line = self.get_line( idx )
+        return line
+    """
+    def set_directive (self, name, line):
+        idx = self._get_last_directive_idx(name)
+        self.set_line( idx, line )
+    """
+    # idx starts from 0 !! it's not a line number    
+    def _get_last_directive_idx (self, name ):
+        last_found = None
+        for key, line in enumerate(self.get_content() ):   
+            if ( self.parser.get_directive(line) == name ): last_found = key            
+        return last_found
+    #TODO create if doesn't exist.
+    def set_directive (self, name, line):
+        idx = self._get_last_directive_idx(name)
+        if ( idx == None ):
+             return self.insert_line( self._last_line_idx() , line.rstrip()+"\n")
+        self.set_line( idx, line.rstrip()+"\n" )
+    
+    def _last_line_idx (self):
+        return 999999
+    
+    def has_option (self, name, option ):
+        line = self.get_directive(name)
+        if ( line == False or line == None ): return False
+        return self.parser.has_option(line, option)  
+    def get_options (self, name):
+        value = self.get_value(name)
+        if value == None: return []
+        options = self.parser.parse_options( value )
+        print options
+        return options
+    def add_option (self, name, option ):    
+        line = self.get_directive(name)
+        if ( line == False or line == None ): 
+            line = name
+            line = name+"\t"+self.parser.value_escape( option )+"\n"    
+            self.insert_line( self._last_line_idx(), line )
+            return
+        line = self.parser.add_option(line, option)
+        self.set_directive(name, line)
+    def remove_option (self, name, option ): 
+        #we need idx later if we decide to remove the whole line
+        idx = self._get_last_directive_idx(name)   
+        line = self.get_directive(name)
+        if ( line == False or line == None ): return False
+        line = self.parser.remove_option(line, option)
+        new_value = self.parser.get_value( line )
+        if ( new_value.strip() == "" ):
+            self.remove_line( idx )
+        else:
+            self.set_directive(name, line)
+    def get_source (self):
+        return "".join( self.get_content() )
+    def get_content(self):
+        return self.content
+    def set_content_from_string(self, string):
+        self.content = string.split( "\n" )
+    def get_line(self, idx):
+        return self.get_content()[idx]
+    def set_line(self, idx, line):
+        self.content[ idx ] = line    
+    def insert_line (self, idx, line):
+        """Inserts a line at the given idx"""
+        if idx >= len( self.content ): #out of range
+            idx = self._last_line_idx()        
+        self.content.insert( idx, line )
+        self.raise_event( 'row_inserted', {'idx':idx, 'line':line } )
+    def remove_line(self, idx ):
+        del self.content[ idx ]
+        self.raise_event( 'row_removed', {'idx':idx } )
+class PieceParser ( Parser ):
+    """Manipulates isolated parts of configuration files. Should be extended"""
+    
+    min = None
+    max = None
+    father = None
+    def apply_observing_policy(self):
+        """register the object with the observer"""
+        self.father.observer.register(self)
+    def load (self, args = {}):
+        print "Please override this method !"
+        exit()
+    def __init__(self, father, args = {} ):
+        self.father = father
+        Parser.__init__( self )
+        self.load( args )
+    def load (self, args = {} ):
+        pass
+    def get_content (self):
+        return self.father.get_content()[ self.min : self.max ]
+
+class VhostParser( PieceParser ):
+    """Searches for the first vhost inside the conf and allows isolated 
+    manipulation  of it"""    
+    
+    def load(self, args = {}): 
+        content = self.father.get_content()
+        self.min = self._find_min(content)
+        if self.min == None:  raise "VhostNotFound", "Beginning not found"
+        self.max = self._find_max(content, self.min) +1
+        if ( self.max == None ): raise "VhostNotFound", "End not found"
+
+    def _last_line_idx (self):
+        return -1
+    def _find_min( self, content ):
+        for idx, line in enumerate( content ):
+            basic_regexp = r'^\s*<s*(VirtualHost)(\s+[^>]*)*>.*'
+            result = re.match( basic_regexp, line, re.IGNORECASE )
+            if ( result != None and result != False ): return idx
+        return None
+    def _find_max( self, content, min ):
+        for idx, line in enumerate( content ):
+            if ( idx > min ):
+                basic_regexp = r'^\s*<s*(/VirtualHost)\s*>.*'
+                result = re.match( basic_regexp, line, re.IGNORECASE )
+                if ( result != None and result != False ): return idx
+        return None
+    def set_line (self, idx, line ):
+        if idx >= 0: idx = idx + self.min
+        return self.father.set_line( idx, line )
+    def insert_line (self, idx, line ):
+        print "===========> INSERTING"
+        if idx >= 0: idx = idx + self.min
+        line = "\t"+line.lstrip() #ident
+        return self.father.insert_line( idx, line )
+    def remove_line(self, idx ):
+        if idx >= 0: idx = idx + self.min
+        return self.father.remove_line( idx )
+    def handle_event(self, event):
+        print self, "handling:", event.name, "raised by", event.caller
+        if ( event.name == 'row_inserted' ):
+            self.max = self.max + 1
+        if ( event.name == 'row_removed' ):
+            self.max = self.max -1
+       
+class LineParser:
+    """Utility class. Contains methods to parse and manipulate apache conf
+    directives"""
+    def tokenize (self, line ):
+        basic_regexp = '^(\s*)([A-Z0-9]+)(\s+)(.*)'  
+        result = re.match( basic_regexp, line, re.IGNORECASE )        
+        if ( result == None ): return False
+        return list( result.groups() )
+    def value_unescape(self, value):
+        #value should have no precedig or trailing spaces
+        if value == "" : return value
+        char = value[0]
+        if char == '"' or char == "'":
+            if char != value[-1]:
+                raise( 'BadQuoting', 'Bad quoting' )
+                return value;
+            value = value[1:-1]
+            value = value.replace( '\\'+char, char )
+            
+        #we don't need to unescape spaces as apparently
+        #apache parser doesn't handle escaped spaces
+        #inside non-quote-enclosed strings
+        return value
+
+    #parse a value into a list of multiple options
+    # - handles double quote-enclosed strings "example"
+    #TODO: doesn't hanlde single quotes at all :(
+    def parse_options ( self, s ):
+        """parse a value into a list of multiple options"""
+        s = s.rstrip()
+        s = s.replace ( '\"', '&quot;' )
+        result = '';    
+        tokens = s.split( '"' )
+        for k, v in enumerate( tokens ):
+            # replace spaces in every odd token
+            if ( k & 1 ) == 1 : tokens[k] = v.replace( ' ', '&nbsp;' )
+
+        s = '"'.join( tokens )
+        s = s.replace( '"', '' )
+        tokens = s.split( ' ' )
+        for k, v in enumerate( tokens ):
+            tokens[ k ] = v.replace( '&nbsp;', ' ' )
+            tokens[ k ] = tokens[ k ].replace( '&quot;', '"' )
+        tokens = [x for x in tokens if x.strip() != '' ]
+        return tokens;
+
+    def remove_option ( self, line, option ):
+        options = self.get_value( line );
+        options = self.parse_options( options);
+        for k,o in enumerate( options ):
+            if ( option == o ): del options[ k ] 
+        
+        return self.change_value( line, " ".join( options ) )
+    def has_option (self, line, option):
+        options = self.parse_options( line )
+        for o in options: 
+            if o == option : return True
+        return False
+    
+    def add_option ( self, line, option ):
+        options = self.get_value( line );
+        if options == False : options = ""   
+        options = self.parse_options( options);
+        found = False;
+        for k,o in enumerate( options ):
+            if ( option == o ): found = True;
+        if ( found == False ): options.append( self.value_escape( option ) )
+        return self.change_raw_value( line, " ".join( options ))
+
+    def value_escape ( self, value ):
+        if ( value.find(' ') != -1 ):
+            value = '"'+value.replace( '"', '\\"' )+'"'
+        return value;
+
+    def get_value ( self, line ):
+        tokens = self.tokenize( line )
+        if ( tokens == False ): return False;
+        value = tokens.pop()
+        value = value.strip()
+        value = self.value_unescape( value )
+        
+        return value
+
+    def get_directive ( self, line ):
+        tokens = self.tokenize( line );        
+        if ( tokens == False ): return False
+        return tokens[ 1 ]
+
+    def change_value( self, line , new_value ):
+        new_value = self.value_escape( new_value )
+        return self.change_raw_value( line, new_value )
+
+    def change_raw_value ( self, line , new_value ):
+        tokens = self.tokenize( line )
+        tokens[2] = tokens[2].replace( "\n", '' ) #separator shuoldn't contain newlines
+        if tokens[2] == '': tokens[2] = ' ' #at least as space as separator
+        line = tokens[0]+tokens[1]+tokens[2]+new_value
+        line = line.rstrip() + "\n"
+        return line
+
+
+if __name__ == "__main__":  
+    
+    parser = Parser()
+    parser.load( '/etc/apache2/sites-available/figa' )
+    parser.set_value('DocumentRoot', '/var/www/xxxx/yyyy' )
+        
+    piece = VhostParser( parser )
+
+    print piece.get_value('DocumentRoot' )
+    print piece.get_value('ServerName' )
+    piece.set_directive( 'fatwife' , 'fatwife 1')
+    
+    #piece.remove_option( 'ServerAlias', 'www.figa' )
+    piece.add_option( 'ServerAlias', 'ftp.figa' ) 
+    
+    
+    print "====="
+    print piece.get_source()
+    print "====="
+ 

=== added file 'RapacheCore/Configuration.py'
--- RapacheCore/Configuration.py	1970-01-01 00:00:00 +0000
+++ RapacheCore/Configuration.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+SYSCONFDIR = '/etc/apache2'
+SITES_ENABLED_DIR = SYSCONFDIR + '/sites-enabled'
+SITES_AVAILABLE_DIR = SYSCONFDIR + '/sites-available'
+MODS_ENABLED_DIR = SYSCONFDIR + '/mods-enabled'
+MODS_AVAILABLE_DIR = SYSCONFDIR + '/mods-available'
+APPPATH = '/usr/bin' #please fill at run-time
+GLADEPATH = '/usr/local/share/rapache/Glade' #please fill at run-time
+

=== added file 'RapacheCore/HostsManager.py'
--- RapacheCore/HostsManager.py	1970-01-01 00:00:00 +0000
+++ RapacheCore/HostsManager.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,299 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import getopt, sys
+import os
+import re
+import subprocess
+"""
+Things to remember:
+    - if 2 equal domain names are found in /etc/hosts the first wins
+"""
+
+# Flow:
+# ------------
+# hosts-manager -a example.loc 10.0.0.1
+#
+# example.loc exists ?
+#   No. Add it at the end of file
+#   Yes
+#       is ip the same ?
+#           yes. Skipping.
+#           no.
+#               remove domain name from the line it first appears in
+#               if the line contained only one domain, remove the line altogheter
+#               add a new line just below $IP    $DOMAIN_NAME
+
+
+#IPv4 REGEXP: \d{1,3}\.\d{1,3}\.\d{1,3}'
+#IPv4 (2): \b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
+#SOSTITUZIONE: re.sub( r'(\s)(www.mu.loc)(\s|$)', r'\3\1xxx\3', subject )
+#CAMBIO IP:
+
+
+#TODO: regexp the crap out of IP's (v4 and v6)
+#TODO: strip in-line comments 127.0.0.1 domain.localhost #strip-this.com
+
+class HostsManager:
+    SUDO = "sudo"
+    HOSTS = "/etc/hosts"
+    REGEXP_IPV4 = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
+    opts = None
+    def __init__( self, console = False ):
+        if ( console ):
+
+            try:
+                opts, args = getopt.getopt(sys.argv[1:], "ho:v:ar", ["help", "output="])
+                self.opts = opts
+                self.args = args
+            except getopt.GetoptError, err:
+                # print help information and exit:
+                print str(err) # will print something like "option -a not recognized"
+                self.usage()
+                sys.exit(2)
+            output = None
+            verbose = False
+            if len(opts) == 0:
+                self.usage()
+                exit()
+            for o, a in opts:
+                if o == "-v":
+                    verbose = True
+                elif o == "-a":                                        
+                    if ( len( args ) == 0 ):                        
+                        self.usage()
+                        sys.exit()
+                    self.create( *args )
+                elif o == "-r":
+                    if ( len( args ) == 0 ):
+                        self.usage()
+                        sys.exit()
+                    self.remove( *args )                    
+                elif o in ("-h", "--help"):
+                    self.usage()
+                    sys.exit()
+                elif o in ("-o", "--output"):
+                    output = a
+                    print args
+                else:
+                    assert False, "unhandled option"
+    def strip_domain ( self, line, domain_name ):
+        domain_regexp = domain_name.replace( '.', '\\.' ) #quote for regexp
+        regexp_just_1_domain = r'^\s*('+self.REGEXP_IPV4+')(\s*)('+domain_regexp+')(\s|$)'
+        if( re.search( regexp_just_1_domain , line, re.IGNORECASE ) ):
+            return False           
+        tokens = re.split( r'(\s*)', line )
+        new_tokens = []
+        changed = False
+        for word in tokens:                                                    
+            if ( word.strip().lower() != domain_name.strip().lower() ):                  
+                if ( changed == True and new_tokens[-1] == ' ' and word == ' ' ):
+                    """ nothing """               
+                else:
+                    new_tokens.append( word )                    
+                changed = False                                                      
+            else:
+                changed = True        
+        line = "".join( new_tokens )
+        return line
+    def _security_check ( self, domain_name, ip ):
+        if ( re.search( '^localhost$', domain_name, re.IGNORECASE )!=None ):
+            print "hosts-manager won't operate localhost. So sorry"
+            return False
+        p = subprocess.Popen("hostname", stdout=subprocess.PIPE)
+        hostname = p.communicate()[0]
+        hostname = hostname.replace( "\n", "" )
+        if ( re.search( '^'+hostname+'$', domain_name, re.IGNORECASE )!=None ):
+            print "The domain name you gave corresponds to local computer's host name. I won't touch it, sorry"
+            return False
+        if ( ip != False ):
+            if ( re.search( '^'+self.REGEXP_IPV4, ip ) == None ):
+                print ip+" is a bad IP"
+                return False
+        return True
+    def _normalize_ip ( self, ip ):
+        if ( ip == None ): ip="127.0.0.1"
+        if ( re.search( '^localhost$', ip, re.IGNORECASE )!=None ):
+            ip="127.0.0.1"
+        return ip    
+    def remove ( self, domain_name ):                
+        if self._security_check( domain_name, False ) == False: return False
+        content = self._get_content()
+        found = self._find_domain( content, domain_name, False )
+        #   self.strip_domain ( found['line'], domain_name )    
+        if found == False: 
+            print 'Domain "'+domain_name+'" not found'
+            return True        
+        content[ found['idx'] ]  = self.strip_domain ( found['line'], domain_name )                                                                                                      
+        if content[ found['idx'] ] == False:
+            #content[ found['idx'] ] = "xxxxxxxxxxxxxxxxx"
+            del content[ found['idx'] ]        
+        self._write( content )
+        
+    def find (self, domain_name, ip = None ):    
+        ip = self._normalize_ip( ip )
+        if self._security_check( domain_name, ip ) == False: return False
+        content = self._get_content()
+        found = self._find_domain( content, domain_name, ip )
+        return found
+        
+    def create( self, domain_name, ip = None ):      
+        ip = self._normalize_ip( ip )
+        if self._security_check( domain_name, ip ) == False: return False
+        content = self._get_content()
+        found = self._find_domain( content, domain_name, ip )
+        if ( found == False ):           
+            print "adding "+ip+" "+domain_name+" at the end of file"
+            content.append( ip+"\t"+domain_name+"\n" )
+        else:        
+            print "Found "+domain_name+" at line "+str(found['idx']+1)                        
+
+            print "Found domain: "+found['domain']+" ("+found['ip']+")"
+            #print domain_regexp       
+            if ( found['domain'].lower() == domain_name.lower()):
+                if ( ip == found['ip'] ):       
+                    print ">>>"+found['line']+"Definition already present, skipping"
+                    return True
+                else:                       
+                    print ">>>"+found['line']
+                    print "Ip differs. "+found['ip']+" has to become "+ip
+                    print "Removing domain name from this line"
+                    print "Creating a new entry in the next line"                        
+                    content[ found['idx'] ]  = self.strip_domain ( found['line'], domain_name )                                                                                              
+                    content[ found['idx']+1: 1 ] = [ ip+"\t"+domain_name+"\n" ]
+                    if content[ found['idx'] ] == False:
+                        content.remove( False )                    
+                    return True
+            else:
+                print ">>>"+line
+                print "Replacing "+domain_name+" at line "+str(found['idx']+1)
+                return True
+                
+        
+                                 
+        self._write( content )
+    
+    def _get_content ( self ):
+        file = open( '/etc/hosts', 'r' )
+        content =  file.readlines()
+        file.close()
+        return content
+    def _find_domain( self, content, domain_name, ip = None ):  
+
+        output = []        
+        domain_regexp = domain_name.replace( '.', '\\.' ) #quote for regexp        
+        found = False
+        # print domain_regexp
+        
+        for idx, line in enumerate( content ):            
+            regexp =     r'^\s*('+self.REGEXP_IPV4+')\s*.*(\s*)('+domain_regexp+')(\s|$)'
+            match = re.search( regexp , line, re.IGNORECASE )                
+            if ( match != None ): 
+                print "Found "+domain_name+" at line "+str(idx+1)
+                found = True                
+                found_entry = match.groups()                          
+                found_ip = found_entry[0]
+                found_domain = found_entry[2]
+                print "Found domain: "+found_domain+" ("+found_ip+")"
+                #print domain_regexp       
+                if ( found_domain.lower() == domain_name.lower()):
+                    result = { 
+                        'domain':found_domain
+                        , 'ip':found_ip
+                        , 'idx': idx
+                        , 'line': line }
+                    
+                    return result
+        return False
+    def _create( self, domain_name, ip = None ):  
+    
+        ip = self._normalize_ip( ip )
+        if self._security_check( domain_name, ip ) == False: return False      
+        
+        return self._find_domain ( domain_name, ip )
+        
+        file = open( '/etc/hosts', 'r' )
+        content =  file.readlines()
+        file.close()
+        
+        output = []        
+        domain_regexp = domain_name.replace( '.', '\\.' ) #quote for regexp        
+        found = False
+        # print domain_regexp
+        
+        for idx, line in enumerate( content ):            
+            regexp =     r'^\s*('+self.REGEXP_IPV4+')\s*.*(\s*)('+domain_regexp+')(\s|$)'
+            match = re.search( regexp , line, re.IGNORECASE )                
+            if ( match != None ): 
+                print "Found "+domain_name+" at line "+str(idx+1)
+                found = True                
+                found_entry = match.groups()                          
+                found_ip = found_entry[0]
+                found_domain = found_entry[2]
+                print "Found domain: "+found_domain+" ("+found_ip+")"
+                #print domain_regexp       
+                if ( found_domain.lower() == domain_name.lower()):
+                    if ( ip == found_ip ):       
+                        print ">>>"+line+"Definition already present, skipping"
+                        break
+                    else:                       
+                        print ">>>"+line
+                        print "Ip differs. "+found_ip+" has to become "+ip
+                        print "Removing domain name from this line"
+                        print "Creating a new entry in the next line"                        
+                        content[ idx ]  = self.strip_domain ( line, domain_name )                                                                                              
+                        content[ idx+1: 1 ] = [ ip+"\t"+domain_name+"\n" ]
+                        if content[ idx ] == False:
+                            content.remove( False )
+                        
+                        break
+                else:
+                    print ">>>"+line
+                    print "Replacing "+domain_name+" at line "+str(idx+1)
+                    break
+        if ( found == False ):           
+            print "adding "+ip+" "+domain_name+" at the end of file"
+            content.append( ip+"\t"+domain_name+"\n" )
+                                 
+        self._write( content )
+    def _write ( self, content ):
+        if ( 0 ): #debug. output without writing to disk
+            for idx, line in enumerate( content ): 
+                print str(idx)+". "+line.replace("\n", '')
+        else:
+            try:
+                dest = open( '/etc/hosts', 'w' )
+                dest.writelines( content )
+                dest.close()
+            except:
+                print "Error writing to file. Do you have the needed permissions?"    
+    def _get_opt ():
+        print 1
+    def usage ( self ):
+        print """Hosts manager v. 0.1
+USAGE: hosts-manager -a hostname [ip]
+       hosts-manager -r hostname [ip]
+
+Options:
+   -a create a new entry in /etc/hosts
+   -r remove an entry in /etc/hosts       
+"""
+    
+
+if __name__ == "__main__":
+    HostsManager( True )

=== added file 'RapacheCore/Module.py'
--- RapacheCore/Module.py	1970-01-01 00:00:00 +0000
+++ RapacheCore/Module.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,225 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import os
+import tempfile
+import re
+from RapacheCore import Configuration
+from RapacheCore import Shell
+from xml.dom.minidom import *
+
+def is_denormalized_module ( fname ):
+    try:   
+        flink = os.readlink( Configuration.MODS_ENABLED_DIR +"/"+fname )
+        flink = os.path.join(os.path.dirname( Configuration.MODS_AVAILABLE_DIR ), flink)                        
+        #no exceptions ? Means it's a link
+        return True
+    except:
+        return False
+    return False
+def is_not_normalizable( fname):
+     dest = Configuration.MODS_AVAILABLE_DIR + "/" + fname
+     return os.path.exists( dest )
+
+def blacklisted ( fname ):
+    if re.match( '.*[~]\s*$', fname ) != None : return True
+    if re.match( '.*.swp$', fname ) != None : return True
+    return False 
+def normalize_module( fname ):
+    print "Normalizing:", fname
+    orig = Configuration.MODS_ENABLED_DIR + "/" + fname
+    dest = Configuration.MODS_AVAILABLE_DIR + "/" + fname    
+    if ( os.path.exists( dest ) == True ):
+        print fname, "already exists in available dir. not even trying"
+        return False
+    command = [ 'mv', orig, dest ]
+    return Shell.command.sudo_execute( command )
+    return  os.path.exists( dest )
+   
+def get_module_dependants ( name, mods_dict ):
+    dependants = []
+    for idx in mods_dict:
+        if idx != name:
+            mod = mods_dict[ idx ]
+            for dependancy in mod.data[ 'dependancies' ]:
+                if dependancy == name: dependants.append( mod.data['name' ] )
+    return dependants
+"""
+def module_list ():
+    list = {}
+    dirList=os.listdir( Configuration.MODS_AVAILABLE_DIR )
+    dirList = [x for x in dirList if blacklisted( x ) == False ]
+    for fname in  dirList :
+        tokens = os.path.splitext( fname )
+        if tokens[1] == '.load':
+            mod = ModuleModel( tokens[0] )
+            try:
+                mod.load()
+            except "VhostUnparsable":
+                pass
+            list[ fname ] = mod
+            mod = None
+    return list
+"""
+def module_list ():
+    list = {}
+ 
+    #load module descriptions
+    module_descriptions = {}    
+    f = open( Configuration.GLADEPATH + "/modules.xml" , "r")
+    xml = f.read()
+    f.close()
+    document = parseString(xml)
+    for node in document.getElementsByTagName("module"):
+        name = node.getAttribute( "name" )
+        if node.firstChild:
+            description = node.firstChild.nodeValue
+            module_descriptions[name] = description
+ 
+    dirList=os.listdir( Configuration.MODS_AVAILABLE_DIR )
+    dirList = [x for x in dirList if blacklisted( x ) == False ]
+    for fname in  dirList :
+        tokens = os.path.splitext( fname )
+        if tokens[1] == '.load':
+           description = None
+           # find a description
+ 
+           if module_descriptions.has_key(tokens[0]):
+               description = module_descriptions[tokens[0]]
+           elif module_descriptions.has_key("mod_" + tokens[0]):
+               description = module_descriptions["mod_" + tokens[0]]
+ 
+           mod = ModuleModel( tokens[0] )
+           mod.data[ 'description' ] = description
+           try:
+                mod.load(  )
+           except "VhostUnparsable":
+               pass
+           list[ fname ] = mod
+           mod = None
+    return list  
+class ModuleModel:
+    
+    def __init__(self, name = None):
+        self.defaults = {
+            'enabled' : False
+            , 'name' : None
+            , 'domain_name': None
+            , 'changed' : False        
+            , 'dependancies' : []          
+        }
+        self.data = {}
+        self.parsable = False
+        self.changed = False
+                
+        self.data = self.defaults
+        if ( name != None ):
+            self.data[ 'name' ] = name
+            self.data[ 'enabled' ] = self.is_enabled()
+
+    def load (self, name = False):        
+        try:
+            #reset everything
+            #print "Loading :\t",name
+            if ( name == False ): name = self.data[ 'name' ]
+            self.data = self.defaults   
+            self.data['name'] = name
+            
+            
+            #print "Loading(b) :\t",self.data[ 'name' ]            
+            options = {}
+            content = self.get_source()                
+            self.__get_dependecies(content)
+            self.parsable = True
+        except:
+            #print "Unparsable by me - unsupported"
+            raise "ModuleUnparsable"
+            return False
+        self.data['configurable'] = \
+                os.path.exists( os.path.join ( Configuration.MODS_AVAILABLE_DIR, self.data['name']+".conf" ))
+            
+        
+        self.data.update( options )
+        #print self.data
+        return True
+    def __get_dependecies(self, content):   
+        content = content.split("\n")
+        dependancies = []
+        for line in content:
+            match = re.match ( r'# Depends:(.*)', line )
+            if match != None:                                 
+                dependancy = match.groups()[0].strip()
+                if dependancy != "" : dependancies.append( dependancy )
+        self.data[ 'dependancies' ] = dependancies
+    def is_enabled ( self ):
+        orig = self.data[ 'name' ] + ".load"              
+        dirList=os.listdir(  Configuration.MODS_ENABLED_DIR )        
+        for fname in dirList:
+            try:                                
+                flink = os.readlink( Configuration.MODS_ENABLED_DIR +"/"+fname )               
+                flink = os.path.join(os.path.dirname( Configuration.MODS_ENABLED_DIR +"/" ), flink)
+                #please note debian brilliantly features a nice set of
+                # mixed absolute and relative links. FREAKS !
+                # the added "/" is also necessary
+                flink = os.path.normpath(flink)               
+                if ( flink == Configuration.MODS_AVAILABLE_DIR+"/"+orig ):
+                    return True
+            except:
+                pass
+          
+        return False
+    
+    def _write(self, complete_path, content ):    
+        tempfilename = tempfile.mktemp()
+        print "creating temporary file "+tempfilename
+        logfile = open( tempfilename , 'w')
+        logfile.write( content )
+        logfile.close()
+        command = ["cp",tempfilename, complete_path]
+        print "copying tempfile in the appropriate location: ",command
+        Shell.command.sudo_execute( command )
+    
+    def toggle( self, status ):
+        "status = True|False"
+        if status:
+            command_name = "a2enmod"
+        else :
+            command_name = "a2dismod"        
+        # set new value
+        #tokens = self.data['name'].split('.')
+        #del tokens[ len( tokens ) -1 ]
+        #name = ".".join(tokens)
+        name = self.data['name']
+        Shell.command.sudo_execute( [command_name, name] )
+        self.data['enabled'] = self.is_enabled()
+        self.changed = True
+     
+    def get_source ( self ):
+        file = open( Configuration.MODS_AVAILABLE_DIR+'/'+self.data['name']+".load", 'r' )
+        content = file.read()
+        file.close()
+        return content
+    def get_configuration ( self ):
+        file = open( Configuration.MODS_AVAILABLE_DIR+'/'+self.data['name']+".conf", 'r' )
+        content = file.read()
+        file.close()
+        return content
+    def save_configuration (self, content):
+        complete_path = file = Configuration.MODS_AVAILABLE_DIR+'/'+self.data['name']+".conf"
+        self._write(complete_path, content)
\ No newline at end of file

=== added file 'RapacheCore/Observer.py'
--- RapacheCore/Observer.py	1970-01-01 00:00:00 +0000
+++ RapacheCore/Observer.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+class Observable (object) :   
+    """Any instance to be observed with PollyObserver should extend
+    this class. Note this differs from the classical Observable
+    implementation because it only allows the object to be observed
+    from a single Observer"""
+    def __init__(self):
+        self.__observer = None
+    def register (self, observer):
+        self.__observer = observer
+    def unregister (self):
+        if ( self.__observer != None):
+            self.__observer.unregister( self )
+            self.__observer = None
+    def handle_event(self, event):
+        """Override this function in subclasses to implement your 
+        own event handling logic"""
+        print self, "- now handling:", event.name, event.args, event
+    def raise_event (self, name, args = {}, no_caller = False ):
+        if no_caller:
+            event = Event( None, name, args )
+        else:
+            event = Event( self, name, args )
+        print '---------------->',event.name , 'raised by' , self
+        if self.__observer != None: self.__observer.notify( event )
+class PollyObserver:
+    """Simple observer derivation. Observes and dispatches events
+    from/to a poll of objects
+    """
+    def __init__(self):
+        self.__observed = []
+    def register(self, obj):
+        """adds an Observable instance to the poll of observed objects
+        and register itself to it."""
+        #print "checking for same obj"
+        for registered_obj in self.__observed:
+            #print obj, ' == ', registered_obj, '??'
+            if obj == registered_obj: return False
+        self.__observed.append( obj )
+        #print "-->",self.__observed
+        obj.register( self )
+        return True
+    def unregister(self, obj):
+        """remove an Observable instance to the poll of observed objects
+        and removes itself from it."""
+        for idx, registered_obj in enumerate( self.__observed ):
+            if obj == registered_obj: 
+                del self.__observed[ idx]
+                obj.unregister()
+                return True
+        return False
+    def get_observed(self):
+        """returns observed object list, mainly for debug purpouses"""
+        return self.__observed
+    def notify (self, event ):
+        """dispatches an event all around"""
+        for registered_obj in self.__observed:            
+            registered_obj.handle_event( event )
+            
+class Event:
+    caller = None
+    name = None
+    args = {}
+    def __init__(self, caller, name, args ):
+        self.caller = caller
+        self.name = name
+        self.args = args

=== added file 'RapacheCore/PluginBase.py'
--- RapacheCore/PluginBase.py	1970-01-01 00:00:00 +0000
+++ RapacheCore/PluginBase.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,61 @@
+from Module import ModuleModel
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+class PluginBaseObject():
+
+	def __init__(self, path):
+			
+		# The path to the plugin
+		self.path = path
+	
+		# module this plugin works with
+		self.module = ""
+		
+		# Define what additional config should be read from vhost file
+		self.vhosts_config = {  } # 0 value | 1 options
+	
+	def is_module_enabled(self):
+		if self.module:
+			module = ModuleModel(self.module)
+			module.load()
+			print "STATUS : " + self.module + " - " + str( module.is_enabled())
+			return module.is_enabled()
+		return True
+		
+	def is_enabled(self):
+		enabled = self.is_module_enabled()
+		
+		#TODO: Method of activating / deactivating plugins
+		
+		return enabled
+		
+	# Customise the module properties window
+	def load_module_properties(self, notebook, module):
+		return True
+
+	# Perform action on module properties save
+	def save_module_properties(self, module):
+		return True
+
+	# Customise the vhost properties window
+	def load_vhost_properties(self, notebook, vhost_data):
+		return True
+		
+	# Perform action on vhost properties save
+	def save_vhost_properties(self, vhost_data):
+		return True

=== added file 'RapacheCore/PluginManager.py'
--- RapacheCore/PluginManager.py	1970-01-01 00:00:00 +0000
+++ RapacheCore/PluginManager.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,52 @@
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import os.path
+import imp
+import sys
+import traceback
+class PluginManager():
+
+	def __init__(self):
+	
+		print "-- Loading plugins --"
+		self.plugins = []
+		self.__add(os.path.join(sys.path[0], "plugins"))
+		self.__add(os.path.expanduser("~/.rapache/plugins"))
+		print ""
+		
+	def __add(self, pluginpath):
+
+		print "checking plugin folder : " + pluginpath
+			
+		if not pluginpath in sys.path:
+			sys.path.insert(0, pluginpath)
+
+		if os.path.exists(pluginpath):
+			for folder in os.listdir(pluginpath):
+				path = os.path.join(pluginpath,folder)
+				if os.path.isdir(path):				
+					try:
+						module = __import__(folder + ".plugin")
+						obj = module.plugin.register(path)
+						self.plugins.append(obj)
+						print "loaded plugin : " + folder
+					except:
+						print "error loading plugin " + folder
+						traceback.print_exc(file=sys.stdout)
+		
+		

=== added file 'RapacheCore/Shell.py'
--- RapacheCore/Shell.py	1970-01-01 00:00:00 +0000
+++ RapacheCore/Shell.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,201 @@
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+
+# <--- shit
+#def command( command ):        
+#    print "COMMAND: "+command
+#    return os.system( command )
+#    """
+#    try:
+#        retcode = call("mycmd" + " myarg", shell=True)
+#        if retcode < 0:
+#            print >>sys.stderr, "Child was terminated by signal", -retcode
+#        else:
+#            print >>sys.stderr, "Child returned", retcode
+#    except OSError, e:
+#        print >>sys.stderr, "Execution failed:", e
+#    """ 
+    
+import sys   
+import gksu2
+import getpass
+import subprocess
+import StringIO
+import sys
+from subprocess import *
+import traceback
+
+class CommandLogEntry:
+
+    def __init__(self, command):
+        self.command = subprocess.list2cmdline(command)
+        self.returncode = None
+        self.output = None
+        self.error = None
+
+
+class CommandHandler:
+
+    def __init__(self):
+        # Verboseness
+        # 0 = No output
+        # 1 = prints the command and its return code
+        # 2 = Command output
+        self.verbose = 0
+        self.command_log = []
+        # let's make the object stateful, no duplicate password
+        # typing needed for our users
+        self.__password = None
+        
+    def __get_password(self, description, prompt="Password: "):
+        
+        ctx = gksu2.Context()
+        ctx.set_message(description)
+        ctx.set_command(subprocess.list2cmdline(["ls","/root"]))
+        ctx.set_grab(True)        
+        
+        return gksu2.ask_password_full(ctx, prompt) # how does su_full invoke keychain options?
+    
+    def __sudo_popen (self, command, password ): 
+        #don't enable the following line
+        #print "using password:", password
+        
+        # prepend sudo to command and allow piping in 
+        command.insert(0, "sudo")
+        command.insert(1, "-S")
+        p = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
+        #we need a try catch to avoid tracebacks to be printed
+        #as they would show the password
+        try:    
+            p.stdin.write( password )
+        except:
+            #don't enable the following line as you password
+            #will be printed out
+            #traceback.print_exc() #<-- CAUTION !
+            
+            print "ERROR: in __sudo_popen()"
+            pass
+        return p
+    
+    def is_auth_needed (self):        
+        if not self.__password: return True
+        
+        #only ASCII chars in the fake pass, or it won't work
+        #because we have not encoding declared in this file
+        #http://www.python.org/dev/peps/pep-0263/
+        fakepass= 'xxxASAISUHAISGHauyguyagUDBhb2156412-,1-2.,1212'
+        command = [ 'head', '/var/log/syslog', '-n 1' ]
+        p = self.__sudo_popen( command, fakepass)
+        output, error = p.communicate()
+        returncode = p.returncode        
+        self.__output(command, returncode, output, error)    
+        print "needs login:", returncode
+        if returncode == 0:
+            return False
+        else:          
+            self.__password = None      
+            return True
+                
+    # Description will be discarded
+    def execute(self, command, description = None ):
+        returncode = 0
+        output = None
+        error = None
+        # excute the command, capture output, error and return code
+        p = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE) 
+        output, error = p.communicate()
+        returncode = p.returncode
+        self.__output(command, returncode, output, error)
+        return (returncode, output, error)
+   
+    def __output (self, command, returncode, output, error ):
+        string_command = subprocess.list2cmdline(command)
+        if self.verbose > 0:
+            print "COMMAND (return code: "+str(returncode)+"): "+ string_command
+        if self.verbose > 1:
+            print output
+        if error:
+            sys.stderr.write( error+"\n")
+        
+    def sudo_reset (self):
+        self.__password = None
+        command = ['sudo', '-K' ]
+        p = Popen( command, stdout=PIPE, stderr=PIPE, stdin=PIPE) 
+        output, error = p.communicate()
+        returncode = p.returncode
+        self.__output(command, returncode, output, error)
+        
+    def sudo_execute(self, command, description = "Super user priviledges are required to perform this operation"):
+        #log = CommandLogEntry(command)
+        #self.command_log.append( log )
+       
+        returncode = 0
+        output = None
+        error = None
+        new_password = None
+        
+        auth_needed = self.is_auth_needed()
+        
+        if auth_needed :            
+            #let's ask the user for a new password
+            if not self.__password :
+                try:
+                    new_password = self.__get_password(description)
+                except:
+                    returncode = 1
+                    error = "Incorrect password"
+            
+        if (not auth_needed) or new_password:
+            #if already authorized let's fake a random password
+            if new_password:
+                password = new_password
+            elif self.__password:
+                password = self.__password
+            else:
+                #let's just fake it. It will work anyways
+                password = 'xxx'            
+            
+            # excute the command, capture output, error and return code
+            p = self.__sudo_popen( command, password )      
+            #p.stdin.write(password) 
+            output, error = p.communicate()
+            returncode = p.returncode
+            self.__output(command, returncode, output, error)
+            
+        if new_password: 
+            self.__password = 'asasasaasas'
+            #self.__password = new_password
+
+        #log.returncode = returncode
+        #log.output = output
+        #log.error = error
+        
+        return (returncode, output, error)
+
+# Look ma'! A singleton !
+command = CommandHandler()    
+    
+if __name__ == "__main__":
+    c = CommandHandler()
+    c.verbose = 2
+    #print c.is_auth_needed()
+    
+    print c.sudo_reset()       
+    code, out, err = c.sudo_execute(["head", "/var/log/syslog"], "Pwd FTW !")
+    code, out, err = c.sudo_execute(["head", "/var/log/syslog"], "Pwd FTW !")
+   
\ No newline at end of file

=== added file 'RapacheCore/VirtualHost.py'
--- RapacheCore/VirtualHost.py	1970-01-01 00:00:00 +0000
+++ RapacheCore/VirtualHost.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,379 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import os
+import tempfile
+import re
+from RapacheCore import Configuration
+from RapacheCore.ApacheConf import *
+from RapacheCore.HostsManager import HostsManager
+from RapacheCore import Shell
+
+VHOST_TEMPLATE = """#created for you by Rapache
+<VirtualHost *>
+	#ServerAdmin webmaster@xxxxxxxxxxx
+	ServerName example
+	DocumentRoot /var/www/examplepath
+</VirtualHost>"""
+
+
+def valid_domain_name ( name ):
+    # TODO: fix regular expression 
+    valid = ( re.search( '^[a-zA-Z0-9.-]+$', name ) != None )
+    return valid
+
+def is_denormalized_vhost ( fname ):
+    try:   
+        flink = os.readlink( Configuration.SITES_ENABLED_DIR +"/"+fname )
+        flink = os.path.join(os.path.dirname( Configuration.SITES_AVAILABLE_DIR ), flink)                        
+        #no exceptions ? Means it's a link
+        return True
+    except:
+        return False
+    return False
+def is_not_normalizable( fname):
+     dest = Configuration.SITES_AVAILABLE_DIR + "/" + fname
+     return os.path.exists( dest )
+ 
+def normalize_vhost( fname ):
+    print "Normalizing:", fname
+    orig = Configuration.SITES_ENABLED_DIR + "/" + fname
+    dest = Configuration.SITES_AVAILABLE_DIR + "/" + fname    
+    if ( os.path.exists( dest ) == True ):
+        print fname, "already exists in available dir. not even trying"
+        return False
+    command = ['mv',orig,dest]
+    code, output, error = Shell.command.sudo_execute( command )
+    return ( code == 0 )
+    return  os.path.exists( dest )
+    
+class VirtualHostModel:
+    
+    def __init__(self, name = None, plugin_manager = None):
+        self.defaults = {
+            'enabled' : False
+            , 'name' : None
+            , 'ServerName': None
+            , 'changed' : False            
+            , 'hack_hosts' : False
+            , 'DocumentRoot' : None            
+        }
+        self.data = {}
+        self.parsable = False
+        self.changed = False
+        self.simulation = False
+        
+        self.data = self.defaults
+        if ( name != None ):
+            self.data[ 'name' ] = name
+            self.data[ 'enabled' ] = self.is_enabled()
+            
+        # Init plugin values so the keys exist
+        if plugin_manager:
+        	for plugin in plugin_manager.plugins:
+        		for key in plugin.vhosts_config.keys():
+        				self.data[ key ] = None
+
+    def _search(self, content, regexp ): 
+        content = content.split( "\n" )           
+        for line in content:
+            match = re.search( regexp , line, re.IGNORECASE )            
+            if ( match != None ) :
+                if match != False:
+                    return match            
+        return False
+    
+    def _get_conf_value(self, content, regexp):        
+        match = self._search(content, regexp )
+        if ( match == False or match == None ): return None
+        found_entry = match.groups()                          
+        found_value = found_entry[0]
+        return found_value
+    def load(self, name = False, plugin_manager = None):
+    	if ( name == False ): name = self.data[ 'name' ]
+    	options = {}    	
+        parser = Parser()
+        parser.load(  os.path.join(Configuration.SITES_AVAILABLE_DIR, name) )
+        try:
+            piece = VhostParser( parser )
+        except "VhostNotFound":
+         	self.parsable = False
+         	return False
+        domain_name = piece.get_value( 'ServerName' )
+        if domain_name == None:
+         	self.parsable = False
+         	#return False
+        options[ 'ServerName' ] = domain_name
+        options[ 'ServerAlias' ] = piece.get_options( 'ServerAlias' )
+        print options[ 'ServerAlias' ]
+        options[ 'DocumentRoot' ] = piece.get_value('DocumentRoot')
+        hosts = HostsManager()
+        if ( domain_name == None or hosts.find ( domain_name ) == False ):
+            options['hack_hosts'] = False
+        else:
+            options['hack_hosts'] = True
+        self.parsable = True
+        
+        # Load plugin values
+        if plugin_manager:
+        	for plugin in plugin_manager.plugins:
+        		for key in plugin.vhosts_config.keys():
+        			if plugin.vhosts_config[key] == 1:
+        				options[ key ] = piece.get_options( key )
+        			else:
+        				options[ key ] = piece.get_value( key )
+        
+        self.data.update( options )
+        return True
+            
+        
+    def loaad (self, name = False):
+        print "Loading Vhosts list"
+        try:
+            #reset everything
+            #print "Loading :\t",name
+            if ( name == False ): name = self.data[ 'name' ]
+            self.data = self.defaults   
+            self.data['name'] = name
+            
+            #print "Loading(b) :\t",self.data[ 'name' ]            
+            options = {}
+            content = self.get_source()        
+            #domain_name = self._get_domain_name(content)
+            domain_regexp = r'^\s*ServerName\s+([A-Za-z0-9.\-_]*)'
+            domain_name = self._get_conf_value(content, domain_regexp)
+            options[ 'ServerName' ] = domain_name
+            domain_regexp = domain_name.replace( '.', '\\.' ) #quote for regexp
+            www_regexp = r'^\s*ServerAlias\s*[^#]*\s+www\.'+domain_regexp+'(\s*|$)'
+            folder_regexp = domain_regexp = r'^\s*DocumentRoot\s+(\S+\s*\S+)'
+            
+            #print "Domain Name :\t"+domain_name             
+            if self._search(content, www_regexp ) != None \
+            and self._search(content, www_regexp ) != False  :
+                options[ 'has_www' ] = True
+            else:
+                options[ 'has_www' ] = False 
+    
+            #print "Has www :\t"+str(options[ 'has_www' ])
+                
+            options[ 'DocumentRoot' ] = self._get_conf_value(content, folder_regexp)
+            
+            #print "Document Root :\t"+str( options[ 'DocumentRoot' ] )
+            hosts = HostsManager()
+            if ( hosts.find ( domain_name ) == False ):
+                options['hack_hosts'] = False
+            else:
+                options['hack_hosts'] = True
+            self.parsable = True
+        except:
+            print "Unparsable by me - unsupported"
+            raise "VhostUnparsable"
+            return False
+        self.data.update( options )
+        #print self.data
+        return True
+        
+    def is_enabled ( self ):
+        orig = self.data[ 'name' ]        
+        dirList=os.listdir(  Configuration.SITES_ENABLED_DIR )
+        for fname in dirList:
+            try:                                
+                flink = os.readlink( Configuration.SITES_ENABLED_DIR +"/"+fname )               
+                flink = os.path.join(os.path.dirname( Configuration.SITES_ENABLED_DIR +"/" ), flink)
+                # please note debian features a nice set of
+                # mixed absolute and relative links. FREAKS !
+                # the added "/" is also necessary
+                flink = os.path.normpath(flink)               
+                if ( flink == Configuration.SITES_AVAILABLE_DIR+"/"+orig ):
+                    return True
+            except:
+                pass
+          
+        return False
+   
+    def toggle( self, status ):
+        "status = True|False"
+        if status:
+    	    command = "a2ensite"
+        else :
+    	    command = "a2dissite"        
+        # set new value
+        if self.simulation:
+            print "SIMULATED ",[ command, self.data['name'] ]
+            self.data['enabled'] = status
+        else:
+            Shell.command.sudo_execute( [ command, self.data['name'] ] )
+            self.data['enabled'] = self.is_enabled()
+        self.changed = True
+        
+    def delete( self ):
+        "Deletes a VirtualHost configuration file"
+        if ( self.is_enabled() ): self.toggle( False )
+        Shell.command.sudo_execute( [ 'rm', Configuration.SITES_AVAILABLE_DIR+'/'+self.data['name'] ])
+    def _create_complete_path ( self, complete_path ):
+        print "Attempting to create: " + complete_path
+        tokens = complete_path.split( '/' )
+        del tokens[ 0 ]        
+        path = ''
+        for piece in tokens:
+            path = path + '/' + piece
+            if ( os.path.exists( path ) == False ):
+                try:
+                    Shell.command.sudo_execute( ["mkdir", path] )
+                except:
+                    print "error on creating path"+path
+                    return False                   
+        print "Created path: " + path
+        return True    
+     
+    def get_source ( self ):
+        file = open( Configuration.SITES_AVAILABLE_DIR+'/'+self.data['name'], 'r' )
+        content = file.read()
+        file.close()
+        return content
+    def update ( self, new_options, name ):
+        print "updating virtual host", name
+        #print new_options        
+        
+        old_enabled = self.is_enabled()
+        print "IS ENABLED", old_enabled
+        parser = Parser()
+        parser.load(  Configuration.SITES_AVAILABLE_DIR+'/'+name )
+        piece = VhostParser( parser )
+        old_servername = piece.get_value( 'ServerName' )
+        
+        # Get a bit more dynamic with it
+        for key in new_options.keys():
+            obj = new_options[key]
+            if isinstance(obj, list):
+                piece.set_value(key, '')
+                for opt in obj:
+                    piece.add_option(key, opt )
+            elif isinstance(obj, str):
+                if obj:
+                    piece.set_value(key, obj)
+                else:
+                    piece.remove_value(key)
+        
+        #piece.set_value('ServerAlias',  '' )
+        #for domain in new_options ['ServerAlias']:
+        #    piece.add_option('ServerAlias', domain )
+                                        
+        print "DocumentRoot From",piece.get_value('DocumentRoot' ),"to",new_options['DocumentRoot']
+        piece.set_value('DocumentRoot', new_options['DocumentRoot'] )
+                
+        print "ServerName From",piece.get_value('ServerName' ),"to",new_options['ServerName']
+        piece.set_value('ServerName', new_options['ServerName'] )                
+        complete_path = Configuration.SITES_AVAILABLE_DIR+'/'+ name 
+        
+        print "Writing.."
+        print parser.get_source()
+        self._write( complete_path, parser.get_source() )
+        
+        #if the servername coincides with the configuration filename
+        #we try to stick with the convention
+        new_name = Configuration.SITES_AVAILABLE_DIR + "/"+ new_options['ServerName']
+        old_name = Configuration.SITES_AVAILABLE_DIR + "/"+ old_servername
+        print "old name", old_name
+        print "new name", new_name
+        
+        if old_name != new_name and os.path.exists( new_name ) == False:
+            print "Server name changed, updating conf filename"
+            self.toggle( False )     
+            Shell.command.sudo_execute( [mv, old_name, new_name] )
+            if os.path.exists( new_name ) == True:
+                #success ! we need to reload vhost with the new name
+                self.load( new_options['ServerName'] )
+                #...so we can toogle it on again
+                if old_enabled == True: 
+                    print "Re-activating"
+                    self.toggle( True )
+                else:
+                    print "Skipping activation"
+            else:
+                print "error! not created:", new_name
+        return True
+    def _write(self, complete_path, content ):    
+        tempfilename = tempfile.mktemp()
+        print "creating temporary file "+tempfilename
+        logfile = open( tempfilename , 'w')
+        logfile.write( content )
+        logfile.close()
+        command = ['cp', tempfilename, complete_path ]
+        print "copying tempfile in the appropriate location: ",command
+        Shell.command.sudo_execute( command )
+                
+    def create ( self, new_options ):                
+        
+        options = self.data
+        options.update( new_options )        
+        
+        #as of creation-time name is not expected to be in options
+        options['name'] = options[ 'ServerName' ]
+        complete_path = Configuration.SITES_AVAILABLE_DIR+'/'+options['name']
+        
+        print options               
+        print "Creating virtualhost: "+options['name']
+        print "Folder: "+options['DocumentRoot']
+        
+        if ( os.path.exists( options['DocumentRoot'] ) == False ): 
+            print "Folder "+options['DocumentRoot']+" does not exist"        
+            self._create_complete_path( options['DocumentRoot'] )
+            
+        if ( os.path.exists( options['DocumentRoot'] ) == False ):
+            self.error( "Could not create target folder" ) #TODO fix this
+            return False
+                       
+        if ( valid_domain_name( options['ServerName'] ) == False ):
+            self.error ( 'Bad domain name: '+options['ServerName'] )
+            return False
+        
+        if os.path.exists( complete_path ):
+            raise "VhostExists", 'Virtual host already exists :('
+            #self.error( 'Virtual host already exists :(' )
+            return False        
+        """
+        template = VHOST_TEMPLATE.replace( '||example||', options['ServerName'] )
+        template = template.replace( '||DocumentRoot||', options['DocumentRoot'] )
+        if ( options[ 'has_www' ] ):
+            template = template.replace( '#ServerAlias www', 'ServerAlias www' )        
+        """
+        parser = Parser()
+        parser.set_content_from_string( VHOST_TEMPLATE )
+        piece = VhostParser( parser )
+        piece.set_value('ServerName',  options['ServerName'] ) 
+        piece.set_value('DocumentRoot',  options['DocumentRoot'] ) 
+
+        print "min", piece.min, "max", piece.max
+        #reset previous aliases
+        piece.set_value('ServerAlias',  '' )
+        for domain in options ['ServerAlias']:
+            piece.add_option('ServerAlias', domain )
+        print parser.get_content()
+            
+        self._write( complete_path, "\n".join(parser.get_content() ) )
+          
+        if ( options[ 'hack_hosts' ] ):
+            Shell.command.sudo_execute ( [Configuration.APPPATH+'/hosts-manager', '-a', options['ServerName'] ] )
+            for alias_name in options[ 'ServerAlias' ]:
+            	Shell.command.sudo_execute ( [Configuration.APPPATH+'/hosts-manager', '-a',alias_name ])
+        self.changed = True        
+        self.toggle( True ) #activate by default 
+            
+        return True

=== added file 'RapacheCore/__init__.py'
=== added directory 'RapacheGtk'
=== renamed directory 'RapacheGtk' => 'RapacheGtk.moved'
=== added file 'RapacheGtk/CheckListView.py'
--- RapacheGtk/CheckListView.py	1970-01-01 00:00:00 +0000
+++ RapacheGtk/CheckListView.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,123 @@
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import gobject
+
+(
+    COLUMN_FIXED,
+    COLUMN_SEVERITY,
+    COLUMN_MARKUP
+) = range(3)
+from RapacheCore import Configuration
+import RapacheCore.Observer
+from RapacheGtk.EventDispatcher import Master
+
+class CheckListView (gtk.TreeView ):
+    """Nice list with icons and checkboxes"""
+    def __init__ (self, *args, **kwargs):                
+        super (CheckListView, self).__init__ (*args, **kwargs)
+        
+        self.toggled_callback = None
+        self.selected_callback = None
+        self.icon_callback = None
+        
+        self.Observable = RapacheCore.Observer.Observable()
+        Master.register(self)
+        
+        self.column_checkbox = None
+        self.column_description = None
+        self.column_icon = None
+        
+        self.__add_columns()
+
+        self.set_headers_visible( False )
+        self.set_rules_hint(True)
+        self.set_search_column(COLUMN_SEVERITY)
+        
+    #----decorating observer    
+    def register (self, *args, **kwargs): return self.Observable.register(*args, **kwargs)
+    def unregister (self, *args, **kwargs): return self.Observable.unregister(*args, **kwargs)
+    def handle_event (self, *args, **kwargs): return self.Observable.handle_event(*args, **kwargs)
+    def raise_event (self, *args, **kwargs): return self.Observable.raise_event(*args, **kwargs)
+    
+    def load (self):
+        raise "AbstractMethod", "Please override this"
+    
+    def _reset_model (self):
+        lstore = self.get_model()
+        if ( lstore == None ):
+            lstore = self._default_model()
+            self.set_model( lstore )
+        else:
+            lstore.clear()
+        return lstore
+    def _default_model (self):
+        lstore = gtk.ListStore(
+                gobject.TYPE_BOOLEAN,
+                gobject.TYPE_STRING,
+                gobject.TYPE_STRING)
+        return lstore
+    
+    def __toggled(self, *args, **kwargs):
+        if self.toggled_callback != None:
+            self.toggled_callback( *args, **kwargs )
+    def __selected(self, *args, **kwargs):
+        if self.selected_callback != None:
+            self.selected_callback( *args, **kwargs )
+    def __icon_requested(self, *args, **kwargs):
+        if self.icon_callback != None:
+            self.icon_callback( *args, **kwargs )       
+                                  
+    def __add_columns(self):
+        #model = self.get_model()
+        # column for fixed toggles
+        renderer = gtk.CellRendererToggle()
+        renderer.connect('toggled', self.__toggled, self)
+        self.column_checkbox = gtk.TreeViewColumn('Enabled', renderer, active=COLUMN_FIXED)
+        self.column_checkbox.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        self.column_checkbox.set_fixed_width(40)
+        self.append_column(self.column_checkbox)
+
+        self.column_icon = gtk.TreeViewColumn()
+        cellRenderer = gtk.CellRendererPixbuf()
+        self.column_icon.pack_start(cellRenderer, expand = False)
+        self.column_icon.set_cell_data_func(cellRenderer, self.__icon_requested )
+        self.append_column(self.column_icon)        
+   
+        self.column_description = gtk.TreeViewColumn('Description', gtk.CellRendererText(),
+                                     markup=COLUMN_MARKUP)
+        self.column_description.set_sort_column_id(COLUMN_MARKUP)
+        self.append_column(self.column_description)
+        self.get_selection().connect("changed", self.__selected )
+        
+    def get_selected_line( self ):
+        #try:
+        selection = self.get_selection()
+        #print '==>', self.get_selected()
+        #print selection.get_selected_rows()[1]
+        try:
+            rows = selection.get_selected_rows()[1][0]
+            num_row = rows[0]
+            model = self.get_model()
+            name = model[ num_row ][1]
+        except IndexError:
+            return None
+        return name
+        #except:
+        #    return None
+
+gobject.type_register (CheckListView)
\ No newline at end of file

=== added file 'RapacheGtk/ConfirmationWindow.py'
--- RapacheGtk/ConfirmationWindow.py	1970-01-01 00:00:00 +0000
+++ RapacheGtk/ConfirmationWindow.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import re
+
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+    
+try:
+    from RapacheCore import Configuration
+except:
+    if __name__ != "__main__":
+        sys.exit(1)
+
+import os
+
+        
+class ConfirmationWindow:
+    
+    def __init__ ( self, parent = None):
+           
+        self.parent = parent
+        self.title = None
+        self.question = None
+        self.return_value = None
+        
+        gladefile = os.path.join(Configuration.GLADEPATH, "confirmation.glade")
+        wtree = gtk.glade.XML(gladefile)
+        
+        self.window = wtree.get_widget("confirmation_window")
+        self.ok_button = wtree.get_widget("ok_button")
+        self.cancel_button = wtree.get_widget("cancel_button")
+        self.question_label = wtree.get_widget("question_label")
+        signals = {
+            "on_ok_button_clicked"       : self.on_ok_button_clicked,
+            "on_cancel_button_clicked"     : self.on_cancel_button_clicked
+        }
+        wtree.signal_autoconnect(signals)
+                
+        # add on destroy to quit loop
+        self.window.connect("destroy", self.on_destroy)
+                
+    def run(self):
+        if self.title: self.window.set_title ( self.title )
+        if self.question: self.question_label.set_text( self.question )
+        
+        self.window.show()           
+        gtk.main()
+
+    def on_destroy(self, widget, data=None):
+        gtk.main_quit()
+
+    def on_ok_button_clicked(self, widget):
+        self.return_value = True
+        self.window.destroy()
+    def on_cancel_button_clicked(self, widget):
+        self.return_value = False
+        self.window.destroy()
+
+def ask_confirmation ( question = None, title = None):
+    win = ConfirmationWindow()
+    win.title = title
+    win.question = question    
+    win.run()
+    answer = win.return_value
+    print "Question: ", question
+    print "Answer: ", answer
+    return answer
+    
+    
+if __name__ == "__main__":
+    class Configuration:
+        GLADEPATH = '../Glade'
+    value = ask_confirmation( 'did you solve bug #1 ?', 'bug confirmation')
+    print '================='
+    print value
+    
+    
\ No newline at end of file

=== added file 'RapacheGtk/DesktopEnvironment.py'
--- RapacheGtk/DesktopEnvironment.py	1970-01-01 00:00:00 +0000
+++ RapacheGtk/DesktopEnvironment.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,44 @@
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import subprocess
+import os
+from RapacheCore import Shell
+
+"""abstracts Desktop Environment's specific operation."""
+# TODO: refactor this into a factory to support more than a Desktop Environment easily
+#
+# care should be taken with userid, we don't want root priviledges when they're not needed
+
+
+# Grabbed from Ubuntu's UpdateManager (ChangelogViewer.py)    
+#  Copyright (c) 2006 Sebastian Heinlein
+#                2007 Canonical    
+# TODO: move this into an utility module        
+def open_url(url):
+    """Opens the specified URL in a browser"""
+    # Find an appropiate browser
+    if os.path.exists('/usr/bin/gnome-open'):
+        command = ['gnome-open', url]
+    else:
+        command = ['x-www-browser', url]
+    # Avoid to run the browser as user root
+    if os.getuid() == 0 and os.environ.has_key('SUDO_USER'):
+        command = ['sudo', '-u', os.environ['SUDO_USER']] + command
+    subprocess.Popen(command)
+# TODO: find out how to open nautilus in background
+def open_dir( path):
+    Shell.command.sudo_execute ( ['nautilus',path, '--no-desktop']  )

=== added file 'RapacheGtk/EditDomainNameGui.py'
--- RapacheGtk/EditDomainNameGui.py	1970-01-01 00:00:00 +0000
+++ RapacheGtk/EditDomainNameGui.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import re
+import os
+
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+
+from RapacheCore.VirtualHost import *
+from RapacheGtk import GuiUtils
+        
+class EditDomainNameWindow:
+
+	def __init__ ( self, domain = ""):
+		self.return_value = None
+		
+		gladefile = os.path.join(Configuration.GLADEPATH, "edit_domain_name.glade")
+		wtree = gtk.glade.XML(gladefile)
+		
+		self.window = wtree.get_widget("dialog_edit_domain_name")
+        	self.entry_domain = wtree.get_widget("entry_domain")
+        	self.label_heading = wtree.get_widget("label_heading")
+        	self.image_icon = wtree.get_widget("image_icon")
+
+        	signals = {
+			"on_button_ok_clicked"        	: self.on_button_ok_clicked,
+			"on_button_cancel_clicked"      : self.on_button_cancel_clicked
+		}
+		wtree.signal_autoconnect(signals)
+		
+		# add on destroy to quit loop
+		self.window.connect("destroy", self.on_destroy)
+		
+		if domain:
+			self.entry_domain.set_text( domain )
+        
+        def run(self):
+        	self.window.show()
+        	self.entry_domain.select_region(0,-1)
+        	gtk.main()
+         	
+        	return self.return_value
+
+        def on_destroy(self, widget, data=None):
+		gtk.main_quit()
+
+	def on_button_ok_clicked(self, widget):
+		self.return_value = self.entry_domain.get_text()
+		self.window.destroy()
+        	return         	
+        	
+	def on_button_cancel_clicked(self, widget):
+		self.window.destroy()
+        	return    
+        	    	

=== added file 'RapacheGtk/EventDispatcher.py'
--- RapacheGtk/EventDispatcher.py	1970-01-01 00:00:00 +0000
+++ RapacheGtk/EventDispatcher.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,19 @@
+import RapacheCore.Observer
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Master = RapacheCore.Observer.PollyObserver()
\ No newline at end of file

=== added file 'RapacheGtk/GuiUtils.py'
--- RapacheGtk/GuiUtils.py	1970-01-01 00:00:00 +0000
+++ RapacheGtk/GuiUtils.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,53 @@
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import gtksourceview2
+import pango
+from RapacheCore import Configuration
+
+def style_as_tooltip( obj ):
+    pw = gtk.Window(gtk.WINDOW_POPUP)
+    pw.set_name('gtk-tooltip')
+    pw.ensure_style()
+    obj.set_style(pw.get_style())
+    obj.connect('expose-event', paint)
+    
+def paint(box, event):
+        box.style.paint_flat_box(box.window, gtk.STATE_NORMAL, gtk.SHADOW_OUT, None, box, "tooltip", box.allocation.x+1, box.allocation.y+1, box.allocation.width-2, box.allocation.height-2)
+
+def change_button_label ( button, new_label ):
+        """Changes the label of a button"""
+        button.show()
+        alignment = button.get_children()[0]
+        hbox = alignment.get_children()[0]
+        image, label = hbox.get_children()
+        label.set_text( new_label )
+
+def new_apache_sourceview():
+    bufferS = gtksourceview2.Buffer()
+    manager = gtksourceview2.LanguageManager()
+    
+    #language = manager.get_language_from_mime_type("text/xml")
+    manager.set_search_path( [ Configuration.GLADEPATH ] + manager.get_search_path() )
+    language = manager.get_language('apache')
+    bufferS.set_language(language)
+    bufferS.set_highlight_syntax(True)
+    sourceview = gtksourceview2.View(bufferS)
+    sourceview.set_show_line_numbers(True)
+    #TODO sniff gnome default monospace font
+    sourceview.modify_font(pango.FontDescription("monospace 10"))
+    return sourceview
\ No newline at end of file

=== added file 'RapacheGtk/ModuleGui.py'
--- RapacheGtk/ModuleGui.py	1970-01-01 00:00:00 +0000
+++ RapacheGtk/ModuleGui.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,139 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+""".
+Issues with the new window:
+    - self.parent doesn't work
+    - onblur doesn't trigger when pressing Return
+    - changing a domain name doesn't change subdomains
+    - empty server aliases shuoldn't be managed
+ALSO:
+    - please implement a delete directive func in the parser
+    - move denorm. vhosts in another tab
+    - merge with Qense warning window
+"""
+
+import sys
+import re
+
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+
+import os
+import pango
+import tempfile
+import traceback
+import RapacheGtk.GuiUtils
+from RapacheCore.Module import *
+from RapacheGtk import GuiUtils
+import RapacheGtk.DesktopEnvironment as Desktop
+
+
+def open_module_doc( name ):
+        if ( name == None ): return False
+        url = "http://httpd.apache.org/docs/2.2/mod/mod_%s.html"; % name
+        Desktop.open_url( url )
+        
+class ModuleWindow:
+    
+    def __init__ ( self, parent = None):
+           
+        self.module = None
+        self.create_new = True
+        self.parent = parent
+        
+        gladefile = os.path.join(Configuration.GLADEPATH, "edit_module.glade")
+        wtree = gtk.glade.XML(gladefile)
+        
+        self.window = wtree.get_widget("dialog_edit_module")
+        #self.text_view_module_conf = wtree.get_widget("text_view_module_conf")
+        self.notebook = wtree.get_widget("notebook")
+        self.button_save = wtree.get_widget("button_save")
+        self.error_area = wtree.get_widget("error_area")
+        self.module_doc_button = wtree.get_widget("module_doc_button")
+        
+        signals = {
+            "on_button_save_clicked"            : self.on_button_save_clicked,
+            "on_button_cancel_clicked"          : self.on_button_cancel_clicked,
+            "on_module_doc_button_clicked"      : self.on_module_doc_button_clicked
+        }
+        wtree.signal_autoconnect(signals)            
+        # add on destroy to quit loop
+        self.window.connect("destroy", self.on_destroy)
+        
+        self.text_view_module_conf = GuiUtils.new_apache_sourceview()        
+        self.text_view_module_conf.show()
+        wtree.get_widget("text_view_module_conf_area").add(self.text_view_module_conf)
+        
+        GuiUtils.change_button_label( self.module_doc_button, 'Documentation' )
+        GuiUtils.style_as_tooltip( self.error_area )
+    def run(self):
+        self.window.show()           
+        gtk.main()
+
+    def load (self, name ):
+        self.window.set_title(name)
+        self.module = ModuleModel ( name )
+        #self.module.load()
+        buf = self.text_view_module_conf.get_buffer()
+        buf.set_text( self.module.get_configuration() )
+        
+         # Load UI Plugins
+        for plugin in self.parent.plugin_manager.plugins:
+        	if plugin.module == name:
+			try:
+				print "Loading plugin " + name
+				plugin.load_module_properties(self.notebook, self.module)
+			except Exception:
+				traceback.print_exc(file=sys.stdout)
+
+    def on_destroy(self, widget, data=None):
+        gtk.main_quit()
+
+    def on_button_save_clicked(self, widget):
+        
+        name = self.module.data['name']
+        print "Current name:", name
+        buff = self.text_view_module_conf.get_buffer()
+        text = buff.get_text(buff.get_start_iter(), buff.get_end_iter())
+
+        mod = ModuleModel( name )
+        mod.save_configuration( text )
+        
+        #self.parent.refresh_vhosts()
+        self.parent.please_restart()
+        self.window.destroy()
+                               
+    def on_button_cancel_clicked(self, widget):
+        self.window.destroy()
+        return    
+    def on_module_doc_button_clicked (self, widget ):
+        name = self.module.data['name']
+        open_module_doc(name)
+    def show_error ( self, message ):
+        
+        self.xml.get_widget( 'message_text' ).set_label( '<b>'+message+'</b>' )
+        self.xml.get_widget( 'message_container' ).show()

=== added file 'RapacheGtk/RapacheGui.py'
--- RapacheGtk/RapacheGui.py	1970-01-01 00:00:00 +0000
+++ RapacheGtk/RapacheGui.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,294 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#TODO throw appropriate exceptions (bug: vhost already exist displays only 
+# after actually trying to create it's dir. check before )
+
+#TODO read ERRORLEVEL from command line operations
+#TODO stop operation if gksudo fails
+#TODO check for sites-enabled-only sites and normalize them
+
+#TODO delete-tarantella: hosts deletion & confirmation
+
+#TODO refuse to edit complex vhosts ( done ? )
+
+import gnome.ui
+import gobject
+import gtk
+import os
+import re
+(
+    COLUMN_FIXED,
+    COLUMN_SEVERITY,
+    COLUMN_MARKUP
+) = range(3)
+
+
+from RapacheGtk.VirtualHostGui import VirtualHostWindow
+from RapacheGtk.ModuleGui import ModuleWindow
+from RapacheCore.PluginManager import PluginManager
+from RapacheGtk.ModuleGui import open_module_doc
+from RapacheCore.VirtualHost import *
+from RapacheGtk import ConfirmationWindow
+from RapacheGtk import GuiUtils
+from RapacheCore import Shell
+import VhostsTreeView
+import RapacheCore.Observer
+from RapacheGtk.EventDispatcher import Master
+import subprocess
+import RapacheGtk.DesktopEnvironment as Desktop
+
+data = \
+[(False, "Loading", "please wait" )]
+
+APPNAME="Rapache"
+APPVERSION="0.6"
+
+
+class MainWindow( RapacheCore.Observer.Observable ) :
+    """This is an Hello World Rapacheefication application"""
+    
+    def __init__(self, *args, **kwargs):
+        super (MainWindow, self).__init__ (*args, **kwargs)
+        Master.register(self)
+
+        self.denormalized_virtual_hosts = {}
+        self.plugin_manager = PluginManager()
+        gnome.init(APPNAME, APPVERSION)
+        self.gladefile = Configuration.GLADEPATH + "/" + "main.glade"  
+        self.xml = gtk.glade.XML(self.gladefile)         
+        #Create our dictionary and connect it
+        dic = { "new_button_clicked" : self.new_button_clicked,
+            "on_MainWindow_destroy" : self.quit ,
+            "please_restart" : self.restart_apache ,            
+            "on_delete" : self.delete_button_clicked,
+            "edit_button_clicked" : self.edit_button_clicked,
+            "edit_module_button_clicked" : self.edit_module_button_clicked,
+            "browse_sites_available" : self.browse_sites_available,
+            "fix_vhosts_clicked" : self.fix_vhosts,
+            "surf_this_button_clicked" : self.surf_this,
+            "browse_button_clicked" : self.browse_this,
+            "about_clicked" : self.display_about,
+            "open_doc_button_clicked" : self.open_doc_button_clicked,
+            "on_button_hide_warning_clicked" : self.on_button_hide_warning_clicked,
+            "quit" : self.quit }
+        gtk.window_set_default_icon(self.xml.get_widget("MainWindow").get_icon())
+        self.xml.signal_autoconnect(dic)
+        GuiUtils.change_button_label ( self.xml.get_widget( 'restart_apache' ), "Restart Apache" )
+        GuiUtils.change_button_label ( self.xml.get_widget( 'fix_vhosts' ), "Fix Virtual Hosts" )
+        #hereby we create lists
+        self.create_vhost_list()
+        self.create_modules_list()
+        #hereby we fill them
+        self.refresh_lists()
+        
+        GuiUtils.style_as_tooltip( self.xml.get_widget( 'restart_apache_notice' ) )
+        GuiUtils.style_as_tooltip( self.xml.get_widget( 'unnormalized_notice' ) )    
+        
+    def on_button_hide_warning_clicked(self, widget):
+        self.xml.get_widget( 'restart_apache_notice' ).hide()
+        
+    def handle_event(self, event ):
+        if event.name == 'please_restart_apache':
+            self.please_restart()
+            return
+        if event.name == 'please_reload_lists':
+            self.load_lists()
+            return
+    def browse_sites_available(self, widget):
+        Desktop.open_dir( Configuration.SITES_AVAILABLE_DIR )
+        return
+    
+    def new_button_clicked(self, widget):
+        new_vhost_window = VirtualHostWindow ( self )
+        #new_vhost_window.load()
+        new_vhost_window.run()
+    def edit_button_clicked(self, widget, notused = None, notused2 = None):         
+        name = self.vhosts_treeview.get_selected_line()
+        print "edit button clicked on:" + name          
+        if ( self.is_vhost_editable( name ) == False ): return False
+        new_vhost_window = VirtualHostWindow ( self )
+        new_vhost_window.load( name )
+        new_vhost_window.run()    
+    def delete_button_clicked( self, widget ):
+        name = self.vhosts_treeview.get_selected_line()
+        if ( self.is_vhost_editable( name ) == False ): return False
+        if ( name == None ): return False
+        result = ConfirmationWindow.ask_confirmation(           
+            "You are about to delete the following domain: \n\n"+name+"\n\nData won't be recoverable. Proceed ?"
+            ,'VirtualHost deletion' )
+        if ( result != True ): return False
+        site = VirtualHostModel( name )
+        site.delete()
+        self.vhosts_treeview.load()
+        self.please_restart()
+    def edit_module_button_clicked(self, widget, notused = None, notused2 = None):
+        name = self.modules_treeview.get_selected_line()
+        if ( self.is_module_editable( name ) == False ): return False
+        print "module edit button clicked on:", name          
+        module_window = ModuleWindow ( self )
+        module_window.load( name )
+        module_window.run()        
+    def quit (self, widget):
+        print 'quitting'
+        gtk.main_quit()
+        exit()
+    
+    def create_vhost_list(self ):
+        #print parent
+        #sw = gtk.ScrolledWindow()
+        sw = self.xml.get_widget( 'vhosts_scroll_box' )      
+        # create virtualhosts treeview
+        treeview = VhostsTreeView.VhostsTreeView()
+        treeview.selected_callback = self.row_selected
+        treeview.connect_after("row-activated", self.edit_button_clicked )
+        self.vhosts_treeview = treeview        
+        self.xml.get_widget( 'vhost_container' ).add(treeview)        
+        self.xml.get_widget( 'vhost_container' ).reorder_child( treeview, 0)
+
+        sw.set_shadow_type(gtk.SHADOW_NONE)
+        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        sw.set_shadow_type(gtk.SHADOW_NONE)
+        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        
+        # create denormalized vhosts.
+        # We check for conf files only present in /etc/apache2/sites-enabled,
+        # display them as a separate list and offer user to normalize them
+        # moving them in /etc/apache2/sites-available and linking them back
+        # from /etc/apache2/sites-enabled
+        
+        denormalized_treeview = VhostsTreeView.DenormalizedVhostsTreeView()
+        self.denormalized_treeview = denormalized_treeview        
+        self.xml.get_widget( 'problems_area' ).add(denormalized_treeview)        
+        self.xml.get_widget( 'problems_area' ).reorder_child( denormalized_treeview, 2)
+        denormalized_treeview.set_sensitive( False )
+        denormalized_treeview.show()
+        sw.show_all()
+        #hidden by default
+        self.xml.get_widget( 'unnormalized_notice' ).hide_all()
+    
+    def create_modules_list(self ):
+        sw = self.xml.get_widget( 'modules_scroll_box' )
+        # create virtualhosts treeview
+        treeview = VhostsTreeView.ModulesTreeView()
+        treeview.connect_after("row-activated", self.edit_module_button_clicked )
+        treeview.selected_callback = self.module_row_selected
+        self.modules_treeview = treeview        
+        self.xml.get_widget( 'modules_container' ).add(treeview)        
+        self.xml.get_widget( 'modules_container' ).reorder_child( treeview, 0)
+        sw.set_shadow_type(gtk.SHADOW_NONE)
+        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        sw.set_shadow_type(gtk.SHADOW_NONE)
+        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        sw.show_all()
+                      
+    def refresh_vhosts ( self ):
+        print "reloading vhosts.."            
+        self.vhosts_treeview.load()
+    def refresh_denormalized_vhosts (self):
+        self.denormalized_treeview.load()
+        if ( len( self.denormalized_treeview.items ) > 0 ):
+            self.xml.get_widget( 'unnormalized_notice' ).show_all()
+            self.xml.get_widget( 'notebook' ).get_nth_page( 2 ).show()
+        else:
+            self.xml.get_widget( 'unnormalized_notice' ).hide_all()
+            self.xml.get_widget( 'notebook' ).get_nth_page( 2 ).hide()
+    def refresh_modules (self):    
+        print "reloading modules.."            
+        self.modules_treeview.load()
+    def refresh_lists (self):
+        self.refresh_vhosts()
+        self.refresh_modules()
+        self.refresh_denormalized_vhosts()
+    def please_restart ( self ):
+        self.xml.get_widget( 'restart_apache_notice' ).show()
+    def restart_apache ( self, widget ):
+        print "Restarting apache on user's request"
+        Shell.command.sudo_execute( ['/etc/init.d/apache2', 'stop'] )
+        Shell.command.sudo_execute( ['/etc/init.d/apache2', 'start'] )
+        self.xml.get_widget( 'restart_apache_notice' ).hide()
+        self.refresh_lists()
+    def is_vhost_editable (self, name):
+        return name != 'default'
+    def is_module_editable (self, name):
+        editable = False
+        if name:
+            mod = self.modules_treeview.items[ name+".load" ]
+            editable = mod.data[ 'configurable' ]
+        return editable
+    def row_selected( self, widget ):
+        name = self.vhosts_treeview.get_selected_line()
+        if ( name == None ):
+            self.xml.get_widget( 'delete_button' ).set_sensitive( False )
+            self.xml.get_widget( 'edit_button' ).set_sensitive( False )
+            self.xml.get_widget( 'open_in_browser_button' ).set_sensitive( False )
+        else:
+            editable = self.is_vhost_editable( name )
+            self.xml.get_widget( 'delete_button' ).set_sensitive( editable )
+            self.xml.get_widget( 'edit_button' ).set_sensitive( editable )
+            surfable =  self.get_current_vhost_directive( 'ServerName' ) != None
+            self.xml.get_widget( 'surf_this_button' ).set_sensitive( surfable )
+            browsable =  self.get_current_vhost_directive( 'DocumentRoot' ) != None
+            self.xml.get_widget( 'browse_button' ).set_sensitive( browsable )
+    def module_row_selected( self, widget):
+        name = self.modules_treeview.get_selected_line()
+        editable = self.is_module_editable(name)
+        self.xml.get_widget( 'edit_module_button' ).set_sensitive( editable )
+        if name != None: self.xml.get_widget( 'open_doc_button' ).set_sensitive( True )
+    # TODO: open doc only for apache2.2 own modules, not third-party (eg mod_php5)
+    # TODO: sniff apache version, don't hardcode it
+    def open_doc_button_clicked( self, widget ):
+        name = self.modules_treeview.get_selected_line()
+        if ( name == None ): return False
+        open_module_doc(name)
+        
+    def fix_vhosts(self, widget):
+        items = self.denormalized_treeview.get_items()
+        for name in items:
+            normalize_vhost( name )
+        #since they were in the enabled, let's enabl'em again
+        for name in items:
+            site = VirtualHostModel( name )
+            site.toggle(True)            
+        self.refresh_vhosts()
+        self.refresh_denormalized_vhosts()
+    def get_current_vhost_directive (self, directive_name ):
+        name = self.vhosts_treeview.get_selected_line()
+        if ( name == None ): return None
+        return self.vhosts_treeview.items[ name ].data[ directive_name ]
+    def surf_this(self, widget):
+        name = self.vhosts_treeview.get_selected_line()
+        if name == 'default':
+            server_name = 'localhost'
+        else:
+            server_name = self.get_current_vhost_directive( 'ServerName' )
+        if ( server_name ): Desktop.open_url( "http://"; + server_name )
+    def browse_this(self, widget):
+        document_root = self.get_current_vhost_directive( 'DocumentRoot' )
+        Desktop.open_dir( document_root )
+        
+
+    def display_about (self, widget):
+        dialog = gtk.AboutDialog()
+        dialog.set_name( APPNAME )
+        dialog.set_version( APPVERSION )
+        dialog.set_authors( ["Rapache Developers\nhttps://launchpad.net/~rapache-devel";] )
+        dialog.set_comments('Rapache is an Apache configurator for Ubuntu/Gnome systems')
+        dialog.set_website('http://launchpad.net/rapache')
+        dialog.run()
+        dialog.destroy()

=== added file 'RapacheGtk/VhostsTreeView.py'
--- RapacheGtk/VhostsTreeView.py	1970-01-01 00:00:00 +0000
+++ RapacheGtk/VhostsTreeView.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,237 @@
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import gobject
+from CheckListView import *
+import os
+import re
+from RapacheCore.VirtualHost import *
+from RapacheCore import Module
+from RapacheCore import Configuration
+
+class ConfFilesTreeView( CheckListView ):
+    def __init__ (self, *args, **kwargs):
+        super (ConfFilesTreeView, self).__init__ (*args, **kwargs)
+        self.items = {}
+    def _blacklisted ( self, fname ):
+        if re.match( '.*[~]\s*$', fname ) != None : return True
+        if re.match( '.*.swp$', fname ) != None : return True
+        return False 
+    def is_empty (self):
+        return len( self.items ) == 0
+    def get_items(self):
+        return self.items
+gobject.type_register (ConfFilesTreeView)
+
+
+class VhostsTreeView ( ConfFilesTreeView ):
+    def __init__ (self, *args, **kwargs):
+        super (VhostsTreeView, self).__init__ (*args, **kwargs)
+        self.icon_callback = self.__get_row_icon  
+        self.toggled_callback = self.__fixed_toggled
+    
+    
+    def load(self):
+        self.items = {}
+        site_template = "<b><big>%s</big></b>\n<small>DocumentRoot: %s</small>"
+        site_unparsable_template = "<b><big>%s</big></b>\n<small><i>Further information not available</i></small>"
+        
+        lstore = self._reset_model()
+            
+        data = []          
+        dirList=os.listdir( Configuration.SITES_AVAILABLE_DIR )
+        dirList = [x for x in dirList if self._blacklisted( x ) == False ]            
+        for fname in  dirList :                        
+            site = VirtualHostModel( fname )
+            try:
+                site.load()
+            except "VhostUnparsable":
+                pass
+            self.items[ fname ] = site
+            site = None
+                            
+        for idx in sorted( self.items ):
+            site = self.items[ idx ]
+            if ( site.parsable ):
+                markup = site_template \
+                % ( site.data['name'] , site.data[ 'DocumentRoot' ] )
+            else:
+                markup = site_unparsable_template % site.data['name']
+            iter = lstore.append()
+            lstore.set(iter,
+                COLUMN_FIXED, site.data['enabled'],
+                COLUMN_SEVERITY, site.data['name'],
+                COLUMN_MARKUP, markup )
+
+    #TODO: warning ! This function get's called even on mousehover
+    #      check for a way to optimize it
+    def __get_row_icon (self, column, cell, model, iter):
+        """ Provides the icon for a virtual host looking up it's favicon"""        
+        """node = model.get_value(iter, MODEL_FIELD_NODE)
+        pixbuf = getPixbufForNode(node)
+        cell.set_property('pixbuf', pixbuf)"""                
+        favicon = os.path.join( Configuration.GLADEPATH, 'browser.png' )
+        fname = model.get_value(iter, COLUMN_SEVERITY )
+        site = self.items[ fname ]
+        if site.data['DocumentRoot'] != None:
+            custom_favicon = os.path.join(os.path.dirname( site.data['DocumentRoot']+"/" ), "favicon.ico")                                                    
+            if ( os.path.exists( custom_favicon ) ): favicon = custom_favicon
+            
+        pixbuf = gtk.gdk.pixbuf_new_from_file( favicon )
+        cell.set_property("pixbuf", pixbuf)
+        
+    def __fixed_toggled(self, cell, path, treeview):        
+        # get toggled iter        
+        model = treeview.get_model()
+        iter = model.get_iter((int(path),))
+        fixed = model.get_value(iter, COLUMN_FIXED)
+        name = model.get_value(iter, COLUMN_SEVERITY)
+
+        fixed = not fixed        
+        if fixed:
+            Shell.command.sudo_execute ( [Configuration.APPPATH+'/hosts-manager', '-a',name])
+        else :
+            Shell.command.sudo_execute ( [Configuration.APPPATH+'/hosts-manager', '-r',name])
+        # set new value        
+        site = VirtualHostModel( name )
+        site.toggle( fixed )
+        model.set(iter, COLUMN_FIXED, site.data['enabled'] )        
+        if ( site.changed ):
+            self.raise_event( 'please_restart_apache' )                
+gobject.type_register (VhostsTreeView)
+
+class DenormalizedVhostsTreeView ( ConfFilesTreeView ):
+    def __init__ (self, *args, **kwargs):
+        super (DenormalizedVhostsTreeView, self).__init__ (*args, **kwargs)
+        print self.column_checkbox, self.column_description, self.column_icon
+        self.column_checkbox.set_visible( False )
+        self.column_icon.get_cell_renderers()[0].set_property( 'stock-id',  gtk.STOCK_DIALOG_WARNING )        
+    def load(self):    
+        self.items = {}
+        site_template = "<b><big>%s</big></b>"        
+        lstore = self._reset_model()
+        
+        data = []  
+        dirList=os.listdir( Configuration.SITES_ENABLED_DIR )
+        dirList = [x for x in dirList if self._blacklisted( x ) == False ]
+        dirList = [x for x in dirList if is_denormalized_vhost( x ) == False ]                   
+        for fname in  dirList :
+            site = VirtualHostModel( fname )                        
+            self.items[ fname ] = site
+            site = None
+
+        for idx in sorted( self.items ):            
+            site = self.items[ idx ]
+            normalizable = not is_not_normalizable(site.data['name'])
+            markup = site_template % site.data['name']
+            if ( normalizable == False ):
+                markup = markup + " CANNOT FIX"
+            iter = lstore.append()
+            lstore.set(iter,
+                COLUMN_FIXED, normalizable,
+                COLUMN_SEVERITY, site.data['name'],
+                COLUMN_MARKUP, markup 
+                )
+    def toggled_callback(self, *args, **kwargs):
+        pass
+gobject.type_register (DenormalizedVhostsTreeView )
+
+class ModulesTreeView ( ConfFilesTreeView ):
+    def __init__ (self, *args, **kwargs):
+        super (ModulesTreeView, self).__init__ (*args, **kwargs)
+        
+        icon_file_name = os.path.join( Configuration.GLADEPATH , "modules.png")
+        pixbuf = gtk.gdk.pixbuf_new_from_file( icon_file_name )
+        
+        self.column_icon.get_cell_renderers()[0].set_property('pixbuf', pixbuf) 
+        self.toggled_callback = self.__fixed_toggled
+        self.selected_callback = self.__selected
+        self.column_description.get_cell_renderers()[0].set_property('wrap-mode', gtk.WRAP_WORD)
+        self.column_description.get_cell_renderers()[0].set_property('wrap-width', 400)
+    def __selected(self, *args, **kwargs ):
+        print "MODULE NAME:", self.get_selected_line()
+        print "DEPENDANTS: ", Module.get_module_dependants(self.get_selected_line(), self.items)
+    def load(self):
+        self.items = {}
+        mod_template = "<b><big>%s</big></b>"
+        mod_unparsable_template = "<b><big>%s</big></b>\n<small><i>Further information not available</i></small>"
+        lstore = self._reset_model()
+        data = []  
+        
+        """dirList=os.listdir( Configuration.MODS_AVAILABLE_DIR )
+        dirList = [x for x in dirList if self._blacklisted( x ) == False ]            
+        for fname in  dirList :                        
+            mod = Module.ModuleModel( fname )
+            try:
+                mod.load()
+            except "VhostUnparsable":
+                pass
+            self.items[ fname ] = mod
+            mod = None
+        """
+        self.items = Module.module_list()
+
+        for idx in sorted( self.items ):
+            mod = self.items[ idx ]
+            if ( mod.parsable ):
+                markup = mod_template \
+                % ( mod.data['name'] ) #, mod.data[ 'DocumentRoot' ] )
+                markup += "\n<small>%s</small>" % mod.data[ 'description' ]
+                if len( mod.data[ 'dependancies' ] ) > 0:
+                    markup += "\n<small><b>%s</b></small>" % ( "Dependencies: " + \
+                    ", ".join( mod.data[ 'dependancies' ] ) )
+                else:
+                    markup += "\n<small><i>No dependencies</i></small>"
+            else:
+                markup = mod_unparsable_template % mod.data['name']
+            iter = lstore.append()
+            lstore.set(iter,
+                COLUMN_FIXED, mod.data['enabled'],
+                COLUMN_SEVERITY, mod.data['name'],
+                COLUMN_MARKUP, markup )
+            
+    def __fixed_toggled(self, cell, path, treeview):        
+        # get toggled iter        
+        model = treeview.get_model()
+        iter = model.get_iter((int(path),))
+        fixed = model.get_value(iter, COLUMN_FIXED)
+        name = model.get_value(iter, COLUMN_SEVERITY)
+        fixed = not fixed        
+        # set new value        
+        mod = Module.ModuleModel( name )
+        mod.toggle( fixed )
+        model.set(iter, COLUMN_FIXED, mod.data['enabled'] )
+        if ( mod.changed ):
+            self.raise_event( 'please_restart_apache' ) 
+        self.raise_event( 'please_reload_lists', {}, True ) 
+    #TODO: warning ! This function get's called even on mousehover
+    #      check for a way to optimize it
+    def __get_row_icon (self, column, cell, model, iter):
+        """ Provides the icon for a module"""        
+        """node = model.get_value(iter, MODEL_FIELD_NODE)
+        pixbuf = getPixbufForNode(node)
+        cell.set_property('pixbuf', pixbuf)"""                
+        favicon = os.path.join( Configuration.GLADEPATH, 'browser.png' )
+        fname = model.get_value(iter, COLUMN_SEVERITY )
+        site = self.items[ fname ]
+        if site.data['DocumentRoot'] != None:
+            custom_favicon = os.path.join(os.path.dirname( site.data['DocumentRoot']+"/" ), "favicon.ico")                                                    
+            if ( os.path.exists( custom_favicon ) ): favicon = custom_favicon
+            
+        pixbuf = gtk.gdk.pixbuf_new_from_file( favicon )
+        cell.set_property("pixbuf", pixbuf)
+gobject.type_register ( ModulesTreeView )

=== added file 'RapacheGtk/VirtualHostGui.py'
--- RapacheGtk/VirtualHostGui.py	1970-01-01 00:00:00 +0000
+++ RapacheGtk/VirtualHostGui.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,295 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+""".
+Issues with the new window:
+    - self.parent doesn't work
+    - onblur doesn't trigger when pressing Return
+    - changing a domain name doesn't change subdomains
+    - empty server aliases shuoldn't be managed
+ALSO:
+    - please implement a delete directive func in the parser
+    - move denorm. vhosts in another tab
+    - merge with Qense warning window
+"""
+
+import sys
+import re
+
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+
+import os
+import pango
+import tempfile
+import traceback
+import RapacheGtk.GuiUtils
+from RapacheCore.VirtualHost import *
+from RapacheGtk import GuiUtils
+from EditDomainNameGui import EditDomainNameWindow
+        
+class VirtualHostWindow:
+    
+    def __init__ ( self, parent = None):
+           
+        self.vhost = None
+        self.create_new = True
+        self.parent = parent
+        self.plugins = []
+
+        gladefile = os.path.join(Configuration.GLADEPATH, "edit_vhost.glade")
+        wtree = gtk.glade.XML(gladefile)
+        
+        self.window = wtree.get_widget("dialog_edit_vhost")
+        self.entry_domain = wtree.get_widget("entry_domain")
+        self.entry_location = wtree.get_widget("entry_location")
+        self.button_location = wtree.get_widget("button_location")
+        self.treeview_domain = wtree.get_widget("treeview_domain")
+        self.checkbutton_hosts = wtree.get_widget("checkbutton_hosts")
+        self.toolbutton_domain_add = wtree.get_widget("toolbutton_domain_add")
+        self.toolbutton_domain_edit = wtree.get_widget("toolbutton_domain_edit")
+        self.toolbutton_domain_delete = wtree.get_widget("toolbutton_domain_delete")
+        self.notebook = wtree.get_widget("notebook")
+        self.button_save = wtree.get_widget("button_save")
+        self.error_area = wtree.get_widget("error_area")
+        signals = {
+            "on_toolbutton_domain_add_clicked"       : self.on_toolbutton_domain_add_clicked,
+            "on_toolbutton_domain_edit_clicked"     : self.on_toolbutton_domain_edit_clicked,
+            "on_toolbutton_domain_delete_clicked"   : self.on_toolbutton_domain_delete_clicked,
+            "on_button_save_clicked"            : self.on_button_save_clicked,
+            "on_button_cancel_clicked"          : self.on_button_cancel_clicked,
+            "on_entry_domain_changed"              : self.on_entry_domain_changed,
+            "on_button_location_clicked"        : self.on_button_location_clicked,
+            "on_entry_domain_focus_out_event"    : self.on_entry_domain_focus_out_event,
+            "on_button_location_clear_clicked"    : self.on_button_location_clear_clicked
+        }
+        wtree.signal_autoconnect(signals)
+        
+        self.text_view_vhost_source = GuiUtils.new_apache_sourceview()
+        wtree.get_widget( 'text_view_vhost_source_area' ).add( self.text_view_vhost_source )
+        self.text_view_vhost_source.set_editable( False )
+        self.text_view_vhost_source.show()
+                
+        self.notebook.get_nth_page( 1 ).hide()
+        self.notebook.get_nth_page( 2 ).hide()
+        
+        # add on destroy to quit loop
+        self.window.connect("destroy", self.on_destroy)
+        
+        # Setup tree
+        column = gtk.TreeViewColumn(('Domains'))
+        column.set_spacing(4)
+        cell = gtk.CellRendererText()
+        column.pack_start(cell, True)
+        column.set_attributes(cell, markup=0)
+        self.treeview_domain.append_column(column)
+        
+        self.treeview_domain_store = gtk.ListStore(str, object)
+        self.treeview_domain.set_model(self.treeview_domain_store)
+
+        GuiUtils.style_as_tooltip( self.error_area )
+        self.on_entry_domain_changed()
+        
+    def run(self):
+
+        # Load UI Plugins
+        if self.vhost:
+            site = self.vhost
+        else:
+            # load default  
+            site = VirtualHostModel( "", self.parent.plugin_manager)
+            
+        for plugin in self.parent.plugin_manager.plugins:
+        	try:
+        	    if plugin.is_enabled():      	        
+        	        plugin.load_vhost_properties(self.notebook, site.data)
+    	        	self.plugins.append(plugin)
+        	except Exception:
+        		traceback.print_exc(file=sys.stdout)
+
+        self.window.show()           
+        gtk.main()
+
+    def load (self, name ):
+        self.vhost = VirtualHostModel( name )
+        self.create_new = False
+        try:
+            self.vhost.load(False, self.parent.plugin_manager)
+            print self.vhost.data
+            #self._get( 'has_www' ).set_active( site.data[ 'has_www' ] )
+            server_name = self.vhost.data[ 'ServerName' ] 
+            if ( server_name != None ):
+                self.entry_domain.set_text( server_name )
+            document_root = self.vhost.data[ 'DocumentRoot' ] 
+            if ( document_root != None ):
+                self.entry_location.set_text( document_root )
+            server_alias = self.vhost.data[ 'ServerAlias' ]
+            if ( server_alias != None ): 
+                for domain in server_alias:
+                    self.treeview_domain_store.append((domain, None))            
+            print self.vhost.data
+        except "VhostUnparsable":            
+            pass
+        
+        buf = self.text_view_vhost_source.get_buffer()
+        buf.set_text( self.vhost.get_source() )
+        
+
+
+    def get_domain (self):
+        return self.entry_domain.get_text().strip()
+        #url.lower().startswith('http://')
+        #url[7:]
+    def set_default_values_from_domain(self, force_domain=False):
+        domain = self.get_domain()
+        
+        # auto set the location
+        if domain and (not self.entry_location.get_text() or force_domain):
+            self.entry_location.set_text( "/srv/www/%s" % (domain +"/httpdocs" ))
+        if force_domain and not domain:
+            self.entry_location.set_text("")
+
+        # auto create a www entry
+        #if not force_domain and domain and len(self.treeview_domain_store) == 0 and not domain.startswith("www"):
+        #    self.treeview_domain_store.append(("www." + domain, None))
+
+    def on_entry_domain_focus_out_event(self, widget, opt):
+        self.set_default_values_from_domain()
+        
+    def on_entry_domain_changed(self, unused_widget = None):
+        widget = self.entry_domain
+        name = widget.get_text()
+        if ( valid_domain_name( name ) ):
+            self.button_save.set_sensitive(True);
+            #if self.create_new :
+            #    self.xml.get_widget( 'default_folder' ).set_text( '/srv/www/'+name+'/httpdocs' )
+        else:
+            self.button_save.set_sensitive(False); 
+    
+    def on_button_location_clear_clicked(self, widget):
+        self.set_default_values_from_domain(True)
+
+
+    def on_button_location_clicked(self, widget):
+        chooser = gtk.FileChooserDialog(
+            title=None,
+            action=gtk.FILE_CHOOSER_ACTION_CREATE_FOLDER,
+                        buttons=(gtk.STOCK_CANCEL,
+                        gtk.RESPONSE_CANCEL,
+                        gtk.STOCK_OPEN,
+                        gtk.RESPONSE_OK))
+                        
+        location = self.entry_location.get_text().strip()
+        if not location:
+            location = "/srv/www"    
+        chooser.set_current_folder(location)
+        response = chooser.run()
+        
+        if response == gtk.RESPONSE_OK:
+            self.entry_location.set_text( chooser.get_filename() )
+        chooser.destroy()
+
+    def on_destroy(self, widget, data=None):
+        gtk.main_quit()
+
+    def on_toolbutton_domain_add_clicked(self, widget):
+        edw = EditDomainNameWindow(self.entry_domain.get_text().strip())
+        domain = edw.run()
+        if domain:
+            self.treeview_domain_store.append((domain, None))
+        return
+    def  get_server_aliases_list (self ):
+        aliases = []
+        for row in self.treeview_domain_store: aliases.append( row[0] )
+        return aliases
+    def on_toolbutton_domain_edit_clicked(self, widget):
+    
+        model, iter = self.treeview_domain.get_selection().get_selected()
+        if not iter: return
+        domain = model.get_value(iter, 0)
+        print domain
+        edw = EditDomainNameWindow( domain )
+        result = edw.run()
+        if result:
+            self.treeview_domain_store.set_value(iter, 0, edw.return_value)
+        return     
+             
+    def on_toolbutton_domain_delete_clicked(self, widget):
+        model, iter = self.treeview_domain.get_selection().get_selected()
+        if not iter: return
+        self.treeview_domain_store.remove(iter)
+        return  
+            
+    def on_button_save_clicked(self, widget):
+        if self.entry_location.get_text() == "" and self.create_new:
+            self.set_default_values_from_domain( True )
+        
+        options = {}
+        options[ 'ServerAlias' ] =  []
+        options[ 'ServerName' ] = self.entry_domain.get_text()
+        options[ 'hack_hosts' ] = self.checkbutton_hosts.get_active()                
+        options[ 'DocumentRoot' ] = self.entry_location.get_text()
+        options[ 'ServerAlias' ] = self.get_server_aliases_list()
+
+	    # Save plugins
+        if self.plugins:
+            for plugin in self.plugins:
+                try:
+                    if plugin.is_enabled():
+                        plugin.save_vhost_properties(options)
+                except Exception:
+                    traceback.print_exc(file=sys.stdout) 
+
+        print options
+        
+        try:
+            if ( self.create_new ):
+                site = VirtualHostModel( options[ 'ServerName' ] )
+                site.create ( options )
+            else:
+                name = self.vhost.data['name']
+                print "Current name:", name
+                site = VirtualHostModel( name )
+                site.update( options, name )
+
+            
+            #self.parent.create_vhost_list()        
+            self.parent.refresh_vhosts()
+            self.parent.please_restart()
+            self.window.destroy()
+        except "VhostExists":
+           print "========================"
+           self.show_error( "A virtual host with the same name already exists" )     
+        
+                         
+    def on_button_cancel_clicked(self, widget):
+        self.window.destroy()
+        return    
+    def show_error ( self, message ):
+        
+        self.xml.get_widget( 'message_text' ).set_label( '<b>'+message+'</b>' )
+        self.xml.get_widget( 'message_container' ).show()                 
+

=== added file 'RapacheGtk/WarningWindow.py'
--- RapacheGtk/WarningWindow.py	1970-01-01 00:00:00 +0000
+++ RapacheGtk/WarningWindow.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+    
+import os
+import gnome.ui
+
+from RapacheGtk import GuiUtils
+from RapacheCore import Configuration
+
+class WarningWindow:
+	"""The Rapache warning window"""
+
+	def __init__(self, warning, father = None):
+		self.father = father
+		self.gladefile = Configuration.GLADEPATH + "/" + "warning_dialog.glade"
+		print self.gladefile
+		self.xml =  gtk.glade.XML(self.gladefile)
+		#Create our dictionary and connect it
+		dic = { 
+			"quit" : gtk.main_quit
+			, "on_ok" : gtk.main_quit
+			}
+		self.xml.signal_autoconnect(dic)
+		self.xml.get_widget( 'label1' ).set_label ( warning )  
+		                  
+

=== added file 'RapacheGtk/__init__.py'
=== added file 'RapacheGtk/old_VirtualHostGui.py'
--- RapacheGtk/old_VirtualHostGui.py	1970-01-01 00:00:00 +0000
+++ RapacheGtk/old_VirtualHostGui.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import re
+
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+
+import os
+import pango
+import tempfile
+
+from RapacheCore.VirtualHost import *
+from RapacheGtk import GuiUtils
+        
+class VirtualHostWindow:
+    
+    create_new = True
+    name = None
+    
+    def __init__ ( self, father = None):
+        self.father = father
+        self.gladefile = Configuration.GLADEPATH + "/" + "edit_vhost.glade"  
+        self.xml = gtk.glade.XML(self.gladefile)     
+        #Create our dictionary and connect it
+        dic = { 
+            "quit" : self.quit
+            , "on_ok":self.save
+            , "on_cancel":self.close  
+            , "domain_name_updated":self.domain_name_updated
+            , "custom_folder_toggled":self.custom_folder_toggled
+            }
+        self.xml.signal_autoconnect(dic)
+        self.xml.get_widget( 'custom_folder' ).set_action ( gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER )                
+        font_desc = pango.FontDescription('monospace')
+        self.xml.get_widget( 'vhost_source' ).modify_font(font_desc)
+        GuiUtils.style_as_tooltip( self.xml.get_widget( 'message_container' ) )
+   
+    def load (self, name ):
+
+        site = VirtualHostModel( name )
+        self.create_new = False
+        self.name = name 
+        self._get( 'create_hosts_entry' ).hide()
+        self._get( 'create_hosts_label' ).hide()
+        try:
+            site.load()
+            self._get( 'has_www' ).set_active( site.data[ 'has_www' ] )
+            self._get( 'domain_name' ).set_text( site.data[ 'ServerName' ] )
+            self._get( 'default_folder' ).set_text( site.data[ 'DocumentRoot' ] )
+            self.xml.get_widget( 'ok_button' ).set_sensitive(True);
+        except "VhostUnparsable":            
+            self._get( 'notebook' ).get_nth_page( 0 ).hide()
+        buffer = self.xml.get_widget( 'vhost_source' ).get_buffer()
+        buffer.set_text( site.get_source() )
+    def _get(self, id ):
+        return self.xml.get_widget( id )
+    
+    
+    def error ( self, message ):
+        self.xml.get_widget( 'message_text' ).set_label( '<b>'+message+'</b>' )
+        self.xml.get_widget( 'message_container' ).show()
+        
+    def quit (self, widget):      
+        self.father.new_vhost_window = None
+    
+    def close ( self, widget = None ):
+        self.window = self.xml.get_widget( 'vhost_edit_window' )
+        self.window.destroy()
+    def domain_name_updated ( self, widget, a = None, b = None, c = None ):
+        name = widget.get_text()
+        if ( valid_domain_name( name ) ):
+            self.xml.get_widget( 'ok_button' ).set_sensitive(True);
+            if self.create_new :
+                self.xml.get_widget( 'default_folder' ).set_text( '/var/www/'+name+'/httpdocs' )
+        else:
+            self.xml.get_widget( 'ok_button' ).set_sensitive(False);
+    def custom_folder_toggled( self, widget ):
+        if ( widget.get_active() == True ):
+            self.xml.get_widget( 'custom_folder' ).show()
+            self.xml.get_widget( 'default_folder' ).hide()
+        else:
+            self.xml.get_widget( 'custom_folder' ).hide()
+            self.xml.get_widget( 'default_folder' ).show()            
+    
+    
+    def save( self, widget ):
+        options = {}
+        options[ 'has_www' ] = self.xml.get_widget( 'has_www' ).get_active()     
+        options[ 'domain_name' ] = ( self.xml.get_widget( 'domain_name' ).get_text() )
+        options[ 'hack_hosts' ] = self.xml.get_widget( 'create_hosts_entry' ).get_active()                
+        if self.xml.get_widget( 'set_custom_folder' ).get_active():
+            DocumentRoot =  self.xml.get_widget( 'custom_folder' ).get_filename ()     
+        else:
+            DocumentRoot =  self.xml.get_widget( 'default_folder' ).get_text()
+        options[ 'DocumentRoot' ] = DocumentRoot
+                       
+        
+        try:
+            if ( self.create_new ):
+                site = VirtualHostModel( options[ 'domain_name' ] )
+                site.create ( options )
+            else:
+                print "Current name:", self.name
+                site = VirtualHostModel( self.name )
+                site.update( options, self.name )
+            
+            self.father.refresh_vhosts()        
+            self.father.please_restart()
+            self.close()
+        except "VhostExists":
+           print "========================"
+           self.error( "A virtual host with the same name already exists" )     
+        
+             
+        return True

=== added file '__init__.py'
=== renamed file '__init__.py' => '__init__.py.moved'
=== added directory 'build'
=== added directory 'build/lib.linux-x86_64-2.6'
=== added directory 'build/lib.linux-x86_64-2.6/RapacheCore'
=== added file 'build/lib.linux-x86_64-2.6/RapacheCore/ApacheConf.py'
--- build/lib.linux-x86_64-2.6/RapacheCore/ApacheConf.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheCore/ApacheConf.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,344 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+ASSUMPTIONS
+    - when multiple directive with the same name are encountered
+      the last one wins.
+    - directives without options could be ok.
+        - ServerAlias without any option works
+        
+GOALS:
+    - change as little as possible when updating to reduce the risk 
+      of breaking something
+      
+TODO:
+    - search for subsections and limit editing to a certain subsection
+    - insert directive where it doesn't exist
+    - remove a directive when it becomes empty (without options)
+    - verify apache handling of case for directives
+"""
+
+import re
+from RapacheCore.Observer import PollyObserver
+from RapacheCore.Observer import Observable
+
+class Parser (Observable):
+    filename = None
+    content = None
+    parser = None
+    
+    def __init__ (self, *args, **kwargs):
+        super (Parser, self).__init__ (*args, **kwargs)
+        self.parser = LineParser()
+        self.apply_observing_policy()
+    
+    def apply_observing_policy(self):
+        """register the object with the observer"""
+        self.observer = PollyObserver()
+        self.observer.register(self)
+        
+    def load(self, filename ):
+        self.filename = filename
+        file = open ( filename, 'r' )
+        self.content = file.readlines()
+        file.close()
+        return self.content
+    
+    def get_value(self, name):
+        line = self.get_directive(name)    
+        if line == None: return None
+        return self.parser.get_value(line)
+    def set_value (self, name, value):
+        idx = self._get_last_directive_idx(name)
+        if idx == None:
+            idx = self._last_line_idx()
+            line = name+"\t"+self.parser.value_escape( value )+"\n"
+            self.insert_line( self._last_line_idx(), line )
+        else:
+            line = self.get_line( idx )
+            line = self.parser.change_value(line, value)
+            self.set_line( idx, line )
+    def remove_value(self, name):
+        idx = self._get_last_directive_idx(name)
+        print "removing line:",idx
+        if idx: 
+            self.remove_line(idx)
+            return True
+        return False
+    def get_directive(self, name):
+        idx = self._get_last_directive_idx(name)
+        if ( idx == None ): return None
+        line = self.get_line( idx )
+        return line
+    """
+    def set_directive (self, name, line):
+        idx = self._get_last_directive_idx(name)
+        self.set_line( idx, line )
+    """
+    # idx starts from 0 !! it's not a line number    
+    def _get_last_directive_idx (self, name ):
+        last_found = None
+        for key, line in enumerate(self.get_content() ):   
+            if ( self.parser.get_directive(line) == name ): last_found = key            
+        return last_found
+    #TODO create if doesn't exist.
+    def set_directive (self, name, line):
+        idx = self._get_last_directive_idx(name)
+        if ( idx == None ):
+             return self.insert_line( self._last_line_idx() , line.rstrip()+"\n")
+        self.set_line( idx, line.rstrip()+"\n" )
+    
+    def _last_line_idx (self):
+        return 999999
+    
+    def has_option (self, name, option ):
+        line = self.get_directive(name)
+        if ( line == False or line == None ): return False
+        return self.parser.has_option(line, option)  
+    def get_options (self, name):
+        value = self.get_value(name)
+        if value == None: return []
+        options = self.parser.parse_options( value )
+        print options
+        return options
+    def add_option (self, name, option ):    
+        line = self.get_directive(name)
+        if ( line == False or line == None ): 
+            line = name
+            line = name+"\t"+self.parser.value_escape( option )+"\n"    
+            self.insert_line( self._last_line_idx(), line )
+            return
+        line = self.parser.add_option(line, option)
+        self.set_directive(name, line)
+    def remove_option (self, name, option ): 
+        #we need idx later if we decide to remove the whole line
+        idx = self._get_last_directive_idx(name)   
+        line = self.get_directive(name)
+        if ( line == False or line == None ): return False
+        line = self.parser.remove_option(line, option)
+        new_value = self.parser.get_value( line )
+        if ( new_value.strip() == "" ):
+            self.remove_line( idx )
+        else:
+            self.set_directive(name, line)
+    def get_source (self):
+        return "".join( self.get_content() )
+    def get_content(self):
+        return self.content
+    def set_content_from_string(self, string):
+        self.content = string.split( "\n" )
+    def get_line(self, idx):
+        return self.get_content()[idx]
+    def set_line(self, idx, line):
+        self.content[ idx ] = line    
+    def insert_line (self, idx, line):
+        """Inserts a line at the given idx"""
+        if idx >= len( self.content ): #out of range
+            idx = self._last_line_idx()        
+        self.content.insert( idx, line )
+        self.raise_event( 'row_inserted', {'idx':idx, 'line':line } )
+    def remove_line(self, idx ):
+        del self.content[ idx ]
+        self.raise_event( 'row_removed', {'idx':idx } )
+class PieceParser ( Parser ):
+    """Manipulates isolated parts of configuration files. Should be extended"""
+    
+    min = None
+    max = None
+    father = None
+    def apply_observing_policy(self):
+        """register the object with the observer"""
+        self.father.observer.register(self)
+    def load (self, args = {}):
+        print "Please override this method !"
+        exit()
+    def __init__(self, father, args = {} ):
+        self.father = father
+        Parser.__init__( self )
+        self.load( args )
+    def load (self, args = {} ):
+        pass
+    def get_content (self):
+        return self.father.get_content()[ self.min : self.max ]
+
+class VhostParser( PieceParser ):
+    """Searches for the first vhost inside the conf and allows isolated 
+    manipulation  of it"""    
+    
+    def load(self, args = {}): 
+        content = self.father.get_content()
+        self.min = self._find_min(content)
+        if self.min == None:  raise "VhostNotFound", "Beginning not found"
+        self.max = self._find_max(content, self.min) +1
+        if ( self.max == None ): raise "VhostNotFound", "End not found"
+
+    def _last_line_idx (self):
+        return -1
+    def _find_min( self, content ):
+        for idx, line in enumerate( content ):
+            basic_regexp = r'^\s*<s*(VirtualHost)(\s+[^>]*)*>.*'
+            result = re.match( basic_regexp, line, re.IGNORECASE )
+            if ( result != None and result != False ): return idx
+        return None
+    def _find_max( self, content, min ):
+        for idx, line in enumerate( content ):
+            if ( idx > min ):
+                basic_regexp = r'^\s*<s*(/VirtualHost)\s*>.*'
+                result = re.match( basic_regexp, line, re.IGNORECASE )
+                if ( result != None and result != False ): return idx
+        return None
+    def set_line (self, idx, line ):
+        if idx >= 0: idx = idx + self.min
+        return self.father.set_line( idx, line )
+    def insert_line (self, idx, line ):
+        print "===========> INSERTING"
+        if idx >= 0: idx = idx + self.min
+        line = "\t"+line.lstrip() #ident
+        return self.father.insert_line( idx, line )
+    def remove_line(self, idx ):
+        if idx >= 0: idx = idx + self.min
+        return self.father.remove_line( idx )
+    def handle_event(self, event):
+        print self, "handling:", event.name, "raised by", event.caller
+        if ( event.name == 'row_inserted' ):
+            self.max = self.max + 1
+        if ( event.name == 'row_removed' ):
+            self.max = self.max -1
+       
+class LineParser:
+    """Utility class. Contains methods to parse and manipulate apache conf
+    directives"""
+    def tokenize (self, line ):
+        basic_regexp = '^(\s*)([A-Z0-9]+)(\s+)(.*)'  
+        result = re.match( basic_regexp, line, re.IGNORECASE )        
+        if ( result == None ): return False
+        return list( result.groups() )
+    def value_unescape(self, value):
+        #value should have no precedig or trailing spaces
+        if value == "" : return value
+        char = value[0]
+        if char == '"' or char == "'":
+            if char != value[-1]:
+                raise( 'BadQuoting', 'Bad quoting' )
+                return value;
+            value = value[1:-1]
+            value = value.replace( '\\'+char, char )
+            
+        #we don't need to unescape spaces as apparently
+        #apache parser doesn't handle escaped spaces
+        #inside non-quote-enclosed strings
+        return value
+
+    #parse a value into a list of multiple options
+    # - handles double quote-enclosed strings "example"
+    #TODO: doesn't hanlde single quotes at all :(
+    def parse_options ( self, s ):
+        """parse a value into a list of multiple options"""
+        s = s.rstrip()
+        s = s.replace ( '\"', '&quot;' )
+        result = '';    
+        tokens = s.split( '"' )
+        for k, v in enumerate( tokens ):
+            # replace spaces in every odd token
+            if ( k & 1 ) == 1 : tokens[k] = v.replace( ' ', '&nbsp;' )
+
+        s = '"'.join( tokens )
+        s = s.replace( '"', '' )
+        tokens = s.split( ' ' )
+        for k, v in enumerate( tokens ):
+            tokens[ k ] = v.replace( '&nbsp;', ' ' )
+            tokens[ k ] = tokens[ k ].replace( '&quot;', '"' )
+        tokens = [x for x in tokens if x.strip() != '' ]
+        return tokens;
+
+    def remove_option ( self, line, option ):
+        options = self.get_value( line );
+        options = self.parse_options( options);
+        for k,o in enumerate( options ):
+            if ( option == o ): del options[ k ] 
+        
+        return self.change_value( line, " ".join( options ) )
+    def has_option (self, line, option):
+        options = self.parse_options( line )
+        for o in options: 
+            if o == option : return True
+        return False
+    
+    def add_option ( self, line, option ):
+        options = self.get_value( line );
+        if options == False : options = ""   
+        options = self.parse_options( options);
+        found = False;
+        for k,o in enumerate( options ):
+            if ( option == o ): found = True;
+        if ( found == False ): options.append( self.value_escape( option ) )
+        return self.change_raw_value( line, " ".join( options ))
+
+    def value_escape ( self, value ):
+        if ( value.find(' ') != -1 ):
+            value = '"'+value.replace( '"', '\\"' )+'"'
+        return value;
+
+    def get_value ( self, line ):
+        tokens = self.tokenize( line )
+        if ( tokens == False ): return False;
+        value = tokens.pop()
+        value = value.strip()
+        value = self.value_unescape( value )
+        
+        return value
+
+    def get_directive ( self, line ):
+        tokens = self.tokenize( line );        
+        if ( tokens == False ): return False
+        return tokens[ 1 ]
+
+    def change_value( self, line , new_value ):
+        new_value = self.value_escape( new_value )
+        return self.change_raw_value( line, new_value )
+
+    def change_raw_value ( self, line , new_value ):
+        tokens = self.tokenize( line )
+        tokens[2] = tokens[2].replace( "\n", '' ) #separator shuoldn't contain newlines
+        if tokens[2] == '': tokens[2] = ' ' #at least as space as separator
+        line = tokens[0]+tokens[1]+tokens[2]+new_value
+        line = line.rstrip() + "\n"
+        return line
+
+
+if __name__ == "__main__":  
+    
+    parser = Parser()
+    parser.load( '/etc/apache2/sites-available/figa' )
+    parser.set_value('DocumentRoot', '/var/www/xxxx/yyyy' )
+        
+    piece = VhostParser( parser )
+
+    print piece.get_value('DocumentRoot' )
+    print piece.get_value('ServerName' )
+    piece.set_directive( 'fatwife' , 'fatwife 1')
+    
+    #piece.remove_option( 'ServerAlias', 'www.figa' )
+    piece.add_option( 'ServerAlias', 'ftp.figa' ) 
+    
+    
+    print "====="
+    print piece.get_source()
+    print "====="
+ 

=== added file 'build/lib.linux-x86_64-2.6/RapacheCore/Configuration.py'
--- build/lib.linux-x86_64-2.6/RapacheCore/Configuration.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheCore/Configuration.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+SYSCONFDIR = '/etc/apache2'
+SITES_ENABLED_DIR = SYSCONFDIR + '/sites-enabled'
+SITES_AVAILABLE_DIR = SYSCONFDIR + '/sites-available'
+MODS_ENABLED_DIR = SYSCONFDIR + '/mods-enabled'
+MODS_AVAILABLE_DIR = SYSCONFDIR + '/mods-available'
+APPPATH = '/usr/bin' #please fill at run-time
+GLADEPATH = '/usr/local/share/rapache/Glade' #please fill at run-time
+

=== added file 'build/lib.linux-x86_64-2.6/RapacheCore/HostsManager.py'
--- build/lib.linux-x86_64-2.6/RapacheCore/HostsManager.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheCore/HostsManager.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,299 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import getopt, sys
+import os
+import re
+import subprocess
+"""
+Things to remember:
+    - if 2 equal domain names are found in /etc/hosts the first wins
+"""
+
+# Flow:
+# ------------
+# hosts-manager -a example.loc 10.0.0.1
+#
+# example.loc exists ?
+#   No. Add it at the end of file
+#   Yes
+#       is ip the same ?
+#           yes. Skipping.
+#           no.
+#               remove domain name from the line it first appears in
+#               if the line contained only one domain, remove the line altogheter
+#               add a new line just below $IP    $DOMAIN_NAME
+
+
+#IPv4 REGEXP: \d{1,3}\.\d{1,3}\.\d{1,3}'
+#IPv4 (2): \b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
+#SOSTITUZIONE: re.sub( r'(\s)(www.mu.loc)(\s|$)', r'\3\1xxx\3', subject )
+#CAMBIO IP:
+
+
+#TODO: regexp the crap out of IP's (v4 and v6)
+#TODO: strip in-line comments 127.0.0.1 domain.localhost #strip-this.com
+
+class HostsManager:
+    SUDO = "sudo"
+    HOSTS = "/etc/hosts"
+    REGEXP_IPV4 = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
+    opts = None
+    def __init__( self, console = False ):
+        if ( console ):
+
+            try:
+                opts, args = getopt.getopt(sys.argv[1:], "ho:v:ar", ["help", "output="])
+                self.opts = opts
+                self.args = args
+            except getopt.GetoptError, err:
+                # print help information and exit:
+                print str(err) # will print something like "option -a not recognized"
+                self.usage()
+                sys.exit(2)
+            output = None
+            verbose = False
+            if len(opts) == 0:
+                self.usage()
+                exit()
+            for o, a in opts:
+                if o == "-v":
+                    verbose = True
+                elif o == "-a":                                        
+                    if ( len( args ) == 0 ):                        
+                        self.usage()
+                        sys.exit()
+                    self.create( *args )
+                elif o == "-r":
+                    if ( len( args ) == 0 ):
+                        self.usage()
+                        sys.exit()
+                    self.remove( *args )                    
+                elif o in ("-h", "--help"):
+                    self.usage()
+                    sys.exit()
+                elif o in ("-o", "--output"):
+                    output = a
+                    print args
+                else:
+                    assert False, "unhandled option"
+    def strip_domain ( self, line, domain_name ):
+        domain_regexp = domain_name.replace( '.', '\\.' ) #quote for regexp
+        regexp_just_1_domain = r'^\s*('+self.REGEXP_IPV4+')(\s*)('+domain_regexp+')(\s|$)'
+        if( re.search( regexp_just_1_domain , line, re.IGNORECASE ) ):
+            return False           
+        tokens = re.split( r'(\s*)', line )
+        new_tokens = []
+        changed = False
+        for word in tokens:                                                    
+            if ( word.strip().lower() != domain_name.strip().lower() ):                  
+                if ( changed == True and new_tokens[-1] == ' ' and word == ' ' ):
+                    """ nothing """               
+                else:
+                    new_tokens.append( word )                    
+                changed = False                                                      
+            else:
+                changed = True        
+        line = "".join( new_tokens )
+        return line
+    def _security_check ( self, domain_name, ip ):
+        if ( re.search( '^localhost$', domain_name, re.IGNORECASE )!=None ):
+            print "hosts-manager won't operate localhost. So sorry"
+            return False
+        p = subprocess.Popen("hostname", stdout=subprocess.PIPE)
+        hostname = p.communicate()[0]
+        hostname = hostname.replace( "\n", "" )
+        if ( re.search( '^'+hostname+'$', domain_name, re.IGNORECASE )!=None ):
+            print "The domain name you gave corresponds to local computer's host name. I won't touch it, sorry"
+            return False
+        if ( ip != False ):
+            if ( re.search( '^'+self.REGEXP_IPV4, ip ) == None ):
+                print ip+" is a bad IP"
+                return False
+        return True
+    def _normalize_ip ( self, ip ):
+        if ( ip == None ): ip="127.0.0.1"
+        if ( re.search( '^localhost$', ip, re.IGNORECASE )!=None ):
+            ip="127.0.0.1"
+        return ip    
+    def remove ( self, domain_name ):                
+        if self._security_check( domain_name, False ) == False: return False
+        content = self._get_content()
+        found = self._find_domain( content, domain_name, False )
+        #   self.strip_domain ( found['line'], domain_name )    
+        if found == False: 
+            print 'Domain "'+domain_name+'" not found'
+            return True        
+        content[ found['idx'] ]  = self.strip_domain ( found['line'], domain_name )                                                                                                      
+        if content[ found['idx'] ] == False:
+            #content[ found['idx'] ] = "xxxxxxxxxxxxxxxxx"
+            del content[ found['idx'] ]        
+        self._write( content )
+        
+    def find (self, domain_name, ip = None ):    
+        ip = self._normalize_ip( ip )
+        if self._security_check( domain_name, ip ) == False: return False
+        content = self._get_content()
+        found = self._find_domain( content, domain_name, ip )
+        return found
+        
+    def create( self, domain_name, ip = None ):      
+        ip = self._normalize_ip( ip )
+        if self._security_check( domain_name, ip ) == False: return False
+        content = self._get_content()
+        found = self._find_domain( content, domain_name, ip )
+        if ( found == False ):           
+            print "adding "+ip+" "+domain_name+" at the end of file"
+            content.append( ip+"\t"+domain_name+"\n" )
+        else:        
+            print "Found "+domain_name+" at line "+str(found['idx']+1)                        
+
+            print "Found domain: "+found['domain']+" ("+found['ip']+")"
+            #print domain_regexp       
+            if ( found['domain'].lower() == domain_name.lower()):
+                if ( ip == found['ip'] ):       
+                    print ">>>"+found['line']+"Definition already present, skipping"
+                    return True
+                else:                       
+                    print ">>>"+found['line']
+                    print "Ip differs. "+found['ip']+" has to become "+ip
+                    print "Removing domain name from this line"
+                    print "Creating a new entry in the next line"                        
+                    content[ found['idx'] ]  = self.strip_domain ( found['line'], domain_name )                                                                                              
+                    content[ found['idx']+1: 1 ] = [ ip+"\t"+domain_name+"\n" ]
+                    if content[ found['idx'] ] == False:
+                        content.remove( False )                    
+                    return True
+            else:
+                print ">>>"+line
+                print "Replacing "+domain_name+" at line "+str(found['idx']+1)
+                return True
+                
+        
+                                 
+        self._write( content )
+    
+    def _get_content ( self ):
+        file = open( '/etc/hosts', 'r' )
+        content =  file.readlines()
+        file.close()
+        return content
+    def _find_domain( self, content, domain_name, ip = None ):  
+
+        output = []        
+        domain_regexp = domain_name.replace( '.', '\\.' ) #quote for regexp        
+        found = False
+        # print domain_regexp
+        
+        for idx, line in enumerate( content ):            
+            regexp =     r'^\s*('+self.REGEXP_IPV4+')\s*.*(\s*)('+domain_regexp+')(\s|$)'
+            match = re.search( regexp , line, re.IGNORECASE )                
+            if ( match != None ): 
+                print "Found "+domain_name+" at line "+str(idx+1)
+                found = True                
+                found_entry = match.groups()                          
+                found_ip = found_entry[0]
+                found_domain = found_entry[2]
+                print "Found domain: "+found_domain+" ("+found_ip+")"
+                #print domain_regexp       
+                if ( found_domain.lower() == domain_name.lower()):
+                    result = { 
+                        'domain':found_domain
+                        , 'ip':found_ip
+                        , 'idx': idx
+                        , 'line': line }
+                    
+                    return result
+        return False
+    def _create( self, domain_name, ip = None ):  
+    
+        ip = self._normalize_ip( ip )
+        if self._security_check( domain_name, ip ) == False: return False      
+        
+        return self._find_domain ( domain_name, ip )
+        
+        file = open( '/etc/hosts', 'r' )
+        content =  file.readlines()
+        file.close()
+        
+        output = []        
+        domain_regexp = domain_name.replace( '.', '\\.' ) #quote for regexp        
+        found = False
+        # print domain_regexp
+        
+        for idx, line in enumerate( content ):            
+            regexp =     r'^\s*('+self.REGEXP_IPV4+')\s*.*(\s*)('+domain_regexp+')(\s|$)'
+            match = re.search( regexp , line, re.IGNORECASE )                
+            if ( match != None ): 
+                print "Found "+domain_name+" at line "+str(idx+1)
+                found = True                
+                found_entry = match.groups()                          
+                found_ip = found_entry[0]
+                found_domain = found_entry[2]
+                print "Found domain: "+found_domain+" ("+found_ip+")"
+                #print domain_regexp       
+                if ( found_domain.lower() == domain_name.lower()):
+                    if ( ip == found_ip ):       
+                        print ">>>"+line+"Definition already present, skipping"
+                        break
+                    else:                       
+                        print ">>>"+line
+                        print "Ip differs. "+found_ip+" has to become "+ip
+                        print "Removing domain name from this line"
+                        print "Creating a new entry in the next line"                        
+                        content[ idx ]  = self.strip_domain ( line, domain_name )                                                                                              
+                        content[ idx+1: 1 ] = [ ip+"\t"+domain_name+"\n" ]
+                        if content[ idx ] == False:
+                            content.remove( False )
+                        
+                        break
+                else:
+                    print ">>>"+line
+                    print "Replacing "+domain_name+" at line "+str(idx+1)
+                    break
+        if ( found == False ):           
+            print "adding "+ip+" "+domain_name+" at the end of file"
+            content.append( ip+"\t"+domain_name+"\n" )
+                                 
+        self._write( content )
+    def _write ( self, content ):
+        if ( 0 ): #debug. output without writing to disk
+            for idx, line in enumerate( content ): 
+                print str(idx)+". "+line.replace("\n", '')
+        else:
+            try:
+                dest = open( '/etc/hosts', 'w' )
+                dest.writelines( content )
+                dest.close()
+            except:
+                print "Error writing to file. Do you have the needed permissions?"    
+    def _get_opt ():
+        print 1
+    def usage ( self ):
+        print """Hosts manager v. 0.1
+USAGE: hosts-manager -a hostname [ip]
+       hosts-manager -r hostname [ip]
+
+Options:
+   -a create a new entry in /etc/hosts
+   -r remove an entry in /etc/hosts       
+"""
+    
+
+if __name__ == "__main__":
+    HostsManager( True )

=== added file 'build/lib.linux-x86_64-2.6/RapacheCore/Module.py'
--- build/lib.linux-x86_64-2.6/RapacheCore/Module.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheCore/Module.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,225 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import os
+import tempfile
+import re
+from RapacheCore import Configuration
+from RapacheCore import Shell
+from xml.dom.minidom import *
+
+def is_denormalized_module ( fname ):
+    try:   
+        flink = os.readlink( Configuration.MODS_ENABLED_DIR +"/"+fname )
+        flink = os.path.join(os.path.dirname( Configuration.MODS_AVAILABLE_DIR ), flink)                        
+        #no exceptions ? Means it's a link
+        return True
+    except:
+        return False
+    return False
+def is_not_normalizable( fname):
+     dest = Configuration.MODS_AVAILABLE_DIR + "/" + fname
+     return os.path.exists( dest )
+
+def blacklisted ( fname ):
+    if re.match( '.*[~]\s*$', fname ) != None : return True
+    if re.match( '.*.swp$', fname ) != None : return True
+    return False 
+def normalize_module( fname ):
+    print "Normalizing:", fname
+    orig = Configuration.MODS_ENABLED_DIR + "/" + fname
+    dest = Configuration.MODS_AVAILABLE_DIR + "/" + fname    
+    if ( os.path.exists( dest ) == True ):
+        print fname, "already exists in available dir. not even trying"
+        return False
+    command = [ 'mv', orig, dest ]
+    return Shell.command.sudo_execute( command )
+    return  os.path.exists( dest )
+   
+def get_module_dependants ( name, mods_dict ):
+    dependants = []
+    for idx in mods_dict:
+        if idx != name:
+            mod = mods_dict[ idx ]
+            for dependancy in mod.data[ 'dependancies' ]:
+                if dependancy == name: dependants.append( mod.data['name' ] )
+    return dependants
+"""
+def module_list ():
+    list = {}
+    dirList=os.listdir( Configuration.MODS_AVAILABLE_DIR )
+    dirList = [x for x in dirList if blacklisted( x ) == False ]
+    for fname in  dirList :
+        tokens = os.path.splitext( fname )
+        if tokens[1] == '.load':
+            mod = ModuleModel( tokens[0] )
+            try:
+                mod.load()
+            except "VhostUnparsable":
+                pass
+            list[ fname ] = mod
+            mod = None
+    return list
+"""
+def module_list ():
+    list = {}
+ 
+    #load module descriptions
+    module_descriptions = {}    
+    f = open( Configuration.GLADEPATH + "/modules.xml" , "r")
+    xml = f.read()
+    f.close()
+    document = parseString(xml)
+    for node in document.getElementsByTagName("module"):
+        name = node.getAttribute( "name" )
+        if node.firstChild:
+            description = node.firstChild.nodeValue
+            module_descriptions[name] = description
+ 
+    dirList=os.listdir( Configuration.MODS_AVAILABLE_DIR )
+    dirList = [x for x in dirList if blacklisted( x ) == False ]
+    for fname in  dirList :
+        tokens = os.path.splitext( fname )
+        if tokens[1] == '.load':
+           description = None
+           # find a description
+ 
+           if module_descriptions.has_key(tokens[0]):
+               description = module_descriptions[tokens[0]]
+           elif module_descriptions.has_key("mod_" + tokens[0]):
+               description = module_descriptions["mod_" + tokens[0]]
+ 
+           mod = ModuleModel( tokens[0] )
+           mod.data[ 'description' ] = description
+           try:
+                mod.load(  )
+           except "VhostUnparsable":
+               pass
+           list[ fname ] = mod
+           mod = None
+    return list  
+class ModuleModel:
+    
+    def __init__(self, name = None):
+        self.defaults = {
+            'enabled' : False
+            , 'name' : None
+            , 'domain_name': None
+            , 'changed' : False        
+            , 'dependancies' : []          
+        }
+        self.data = {}
+        self.parsable = False
+        self.changed = False
+                
+        self.data = self.defaults
+        if ( name != None ):
+            self.data[ 'name' ] = name
+            self.data[ 'enabled' ] = self.is_enabled()
+
+    def load (self, name = False):        
+        try:
+            #reset everything
+            #print "Loading :\t",name
+            if ( name == False ): name = self.data[ 'name' ]
+            self.data = self.defaults   
+            self.data['name'] = name
+            
+            
+            #print "Loading(b) :\t",self.data[ 'name' ]            
+            options = {}
+            content = self.get_source()                
+            self.__get_dependecies(content)
+            self.parsable = True
+        except:
+            #print "Unparsable by me - unsupported"
+            raise "ModuleUnparsable"
+            return False
+        self.data['configurable'] = \
+                os.path.exists( os.path.join ( Configuration.MODS_AVAILABLE_DIR, self.data['name']+".conf" ))
+            
+        
+        self.data.update( options )
+        #print self.data
+        return True
+    def __get_dependecies(self, content):   
+        content = content.split("\n")
+        dependancies = []
+        for line in content:
+            match = re.match ( r'# Depends:(.*)', line )
+            if match != None:                                 
+                dependancy = match.groups()[0].strip()
+                if dependancy != "" : dependancies.append( dependancy )
+        self.data[ 'dependancies' ] = dependancies
+    def is_enabled ( self ):
+        orig = self.data[ 'name' ] + ".load"              
+        dirList=os.listdir(  Configuration.MODS_ENABLED_DIR )        
+        for fname in dirList:
+            try:                                
+                flink = os.readlink( Configuration.MODS_ENABLED_DIR +"/"+fname )               
+                flink = os.path.join(os.path.dirname( Configuration.MODS_ENABLED_DIR +"/" ), flink)
+                #please note debian brilliantly features a nice set of
+                # mixed absolute and relative links. FREAKS !
+                # the added "/" is also necessary
+                flink = os.path.normpath(flink)               
+                if ( flink == Configuration.MODS_AVAILABLE_DIR+"/"+orig ):
+                    return True
+            except:
+                pass
+          
+        return False
+    
+    def _write(self, complete_path, content ):    
+        tempfilename = tempfile.mktemp()
+        print "creating temporary file "+tempfilename
+        logfile = open( tempfilename , 'w')
+        logfile.write( content )
+        logfile.close()
+        command = ["cp",tempfilename, complete_path]
+        print "copying tempfile in the appropriate location: ",command
+        Shell.command.sudo_execute( command )
+    
+    def toggle( self, status ):
+        "status = True|False"
+        if status:
+            command_name = "a2enmod"
+        else :
+            command_name = "a2dismod"        
+        # set new value
+        #tokens = self.data['name'].split('.')
+        #del tokens[ len( tokens ) -1 ]
+        #name = ".".join(tokens)
+        name = self.data['name']
+        Shell.command.sudo_execute( [command_name, name] )
+        self.data['enabled'] = self.is_enabled()
+        self.changed = True
+     
+    def get_source ( self ):
+        file = open( Configuration.MODS_AVAILABLE_DIR+'/'+self.data['name']+".load", 'r' )
+        content = file.read()
+        file.close()
+        return content
+    def get_configuration ( self ):
+        file = open( Configuration.MODS_AVAILABLE_DIR+'/'+self.data['name']+".conf", 'r' )
+        content = file.read()
+        file.close()
+        return content
+    def save_configuration (self, content):
+        complete_path = file = Configuration.MODS_AVAILABLE_DIR+'/'+self.data['name']+".conf"
+        self._write(complete_path, content)
\ No newline at end of file

=== added file 'build/lib.linux-x86_64-2.6/RapacheCore/Observer.py'
--- build/lib.linux-x86_64-2.6/RapacheCore/Observer.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheCore/Observer.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+class Observable (object) :   
+    """Any instance to be observed with PollyObserver should extend
+    this class. Note this differs from the classical Observable
+    implementation because it only allows the object to be observed
+    from a single Observer"""
+    def __init__(self):
+        self.__observer = None
+    def register (self, observer):
+        self.__observer = observer
+    def unregister (self):
+        if ( self.__observer != None):
+            self.__observer.unregister( self )
+            self.__observer = None
+    def handle_event(self, event):
+        """Override this function in subclasses to implement your 
+        own event handling logic"""
+        print self, "- now handling:", event.name, event.args, event
+    def raise_event (self, name, args = {}, no_caller = False ):
+        if no_caller:
+            event = Event( None, name, args )
+        else:
+            event = Event( self, name, args )
+        print '---------------->',event.name , 'raised by' , self
+        if self.__observer != None: self.__observer.notify( event )
+class PollyObserver:
+    """Simple observer derivation. Observes and dispatches events
+    from/to a poll of objects
+    """
+    def __init__(self):
+        self.__observed = []
+    def register(self, obj):
+        """adds an Observable instance to the poll of observed objects
+        and register itself to it."""
+        #print "checking for same obj"
+        for registered_obj in self.__observed:
+            #print obj, ' == ', registered_obj, '??'
+            if obj == registered_obj: return False
+        self.__observed.append( obj )
+        #print "-->",self.__observed
+        obj.register( self )
+        return True
+    def unregister(self, obj):
+        """remove an Observable instance to the poll of observed objects
+        and removes itself from it."""
+        for idx, registered_obj in enumerate( self.__observed ):
+            if obj == registered_obj: 
+                del self.__observed[ idx]
+                obj.unregister()
+                return True
+        return False
+    def get_observed(self):
+        """returns observed object list, mainly for debug purpouses"""
+        return self.__observed
+    def notify (self, event ):
+        """dispatches an event all around"""
+        for registered_obj in self.__observed:            
+            registered_obj.handle_event( event )
+            
+class Event:
+    caller = None
+    name = None
+    args = {}
+    def __init__(self, caller, name, args ):
+        self.caller = caller
+        self.name = name
+        self.args = args

=== added file 'build/lib.linux-x86_64-2.6/RapacheCore/PluginBase.py'
--- build/lib.linux-x86_64-2.6/RapacheCore/PluginBase.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheCore/PluginBase.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,61 @@
+from Module import ModuleModel
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+class PluginBaseObject():
+
+	def __init__(self, path):
+			
+		# The path to the plugin
+		self.path = path
+	
+		# module this plugin works with
+		self.module = ""
+		
+		# Define what additional config should be read from vhost file
+		self.vhosts_config = {  } # 0 value | 1 options
+	
+	def is_module_enabled(self):
+		if self.module:
+			module = ModuleModel(self.module)
+			module.load()
+			print "STATUS : " + self.module + " - " + str( module.is_enabled())
+			return module.is_enabled()
+		return True
+		
+	def is_enabled(self):
+		enabled = self.is_module_enabled()
+		
+		#TODO: Method of activating / deactivating plugins
+		
+		return enabled
+		
+	# Customise the module properties window
+	def load_module_properties(self, notebook, module):
+		return True
+
+	# Perform action on module properties save
+	def save_module_properties(self, module):
+		return True
+
+	# Customise the vhost properties window
+	def load_vhost_properties(self, notebook, vhost_data):
+		return True
+		
+	# Perform action on vhost properties save
+	def save_vhost_properties(self, vhost_data):
+		return True

=== added file 'build/lib.linux-x86_64-2.6/RapacheCore/PluginManager.py'
--- build/lib.linux-x86_64-2.6/RapacheCore/PluginManager.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheCore/PluginManager.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,52 @@
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import os.path
+import imp
+import sys
+import traceback
+class PluginManager():
+
+	def __init__(self):
+	
+		print "-- Loading plugins --"
+		self.plugins = []
+		self.__add(os.path.join(sys.path[0], "plugins"))
+		self.__add(os.path.expanduser("~/.rapache/plugins"))
+		print ""
+		
+	def __add(self, pluginpath):
+
+		print "checking plugin folder : " + pluginpath
+			
+		if not pluginpath in sys.path:
+			sys.path.insert(0, pluginpath)
+
+		if os.path.exists(pluginpath):
+			for folder in os.listdir(pluginpath):
+				path = os.path.join(pluginpath,folder)
+				if os.path.isdir(path):				
+					try:
+						module = __import__(folder + ".plugin")
+						obj = module.plugin.register(path)
+						self.plugins.append(obj)
+						print "loaded plugin : " + folder
+					except:
+						print "error loading plugin " + folder
+						traceback.print_exc(file=sys.stdout)
+		
+		

=== added file 'build/lib.linux-x86_64-2.6/RapacheCore/Shell.py'
--- build/lib.linux-x86_64-2.6/RapacheCore/Shell.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheCore/Shell.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,201 @@
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+
+# <--- shit
+#def command( command ):        
+#    print "COMMAND: "+command
+#    return os.system( command )
+#    """
+#    try:
+#        retcode = call("mycmd" + " myarg", shell=True)
+#        if retcode < 0:
+#            print >>sys.stderr, "Child was terminated by signal", -retcode
+#        else:
+#            print >>sys.stderr, "Child returned", retcode
+#    except OSError, e:
+#        print >>sys.stderr, "Execution failed:", e
+#    """ 
+
+import sys 
+import gksu2
+import getpass
+import subprocess
+import StringIO
+import sys
+from subprocess import *
+import traceback
+
+class CommandLogEntry:
+
+    def __init__(self, command):
+        self.command = subprocess.list2cmdline(command)
+        self.returncode = None
+        self.output = None
+        self.error = None
+
+
+class CommandHandler:
+
+    def __init__(self):
+        # Verboseness
+        # 0 = No output
+        # 1 = prints the command and its return code
+        # 2 = Command output
+        self.verbose = 0
+        self.command_log = []
+        # let's make the object stateful, no duplicate password
+        # typing needed for our users
+        self.__password = None
+        
+    def __get_password(self, description, prompt="Password: "):
+        
+        ctx = gksu2.Context()
+        ctx.set_message(description)
+        ctx.set_command(subprocess.list2cmdline(["ls","/root"]))
+        ctx.set_grab(True)        
+        
+        return gksu2.ask_password_full(ctx, prompt) # how does su_full invoke keychain options?
+    
+    def __sudo_popen (self, command, password ): 
+        #don't enable the following line
+        #print "using password:", password
+        
+        # prepend sudo to command and allow piping in 
+        command.insert(0, "sudo")
+        command.insert(1, "-S")
+        p = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
+        #we need a try catch to avoid tracebacks to be printed
+        #as they would show the password
+        try:    
+            p.stdin.write( password )
+        except:
+            #don't enable the following line as you password
+            #will be printed out
+            #traceback.print_exc() #<-- CAUTION !
+            
+            print "ERROR: in __sudo_popen()"
+            pass
+        return p
+    
+    def is_auth_needed (self):        
+        if not self.__password: return True
+        
+        #only ASCII chars in the fake pass, or it won't work
+        #because we have not encoding declared in this file
+        #http://www.python.org/dev/peps/pep-0263/
+        fakepass= 'xxxASAISUHAISGHauyguyagUDBhb2156412-,1-2.,1212'
+        command = [ 'head', '/var/log/syslog', '-n 1' ]
+        p = self.__sudo_popen( command, fakepass)
+        output, error = p.communicate()
+        returncode = p.returncode        
+        self.__output(command, returncode, output, error)    
+        print "needs login:", returncode
+        if returncode == 0:
+            return False
+        else:          
+            self.__password = None      
+            return True
+                
+    # Description will be discarded
+    def execute(self, command, description = None ):
+        returncode = 0
+        output = None
+        error = None
+        # excute the command, capture output, error and return code
+        p = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE) 
+        output, error = p.communicate()
+        returncode = p.returncode
+        self.__output(command, returncode, output, error)
+        return (returncode, output, error)
+   
+    def __output (self, command, returncode, output, error ):
+        string_command = subprocess.list2cmdline(command)
+        if self.verbose > 0:
+            print "COMMAND (return code: "+str(returncode)+"): "+ string_command
+        if self.verbose > 1:
+            print output
+        if error:
+            sys.stderr.write( error+"\n")
+        
+    def sudo_reset (self):
+        self.__password = None
+        command = ['sudo', '-K' ]
+        p = Popen( command, stdout=PIPE, stderr=PIPE, stdin=PIPE) 
+        output, error = p.communicate()
+        returncode = p.returncode
+        self.__output(command, returncode, output, error)
+        
+    def sudo_execute(self, command, description = "Super user priviledges are required to perform this operation"):
+        #log = CommandLogEntry(command)
+        #self.command_log.append( log )
+       
+        returncode = 0
+        output = None
+        error = None
+        new_password = None
+        
+        auth_needed = self.is_auth_needed()
+        
+        if auth_needed :            
+            #let's ask the user for a new password
+            if not self.__password :
+                try:
+                    new_password = self.__get_password(description)
+                except:
+                    returncode = 1
+                    error = "Incorrect password"
+            
+        if (not auth_needed) or new_password:
+            #if already authorized let's fake a random password
+            if new_password:
+                password = new_password
+            elif self.__password:
+                password = self.__password
+            else:
+                #let's just fake it. It will work anyways
+                password = 'xxx'            
+            
+            # excute the command, capture output, error and return code
+            p = self.__sudo_popen( command, password )      
+            #p.stdin.write(password) 
+            output, error = p.communicate()
+            returncode = p.returncode
+            self.__output(command, returncode, output, error)
+            
+        if new_password: 
+            self.__password = 'asasasaasas'
+            #self.__password = new_password
+
+        #log.returncode = returncode
+        #log.output = output
+        #log.error = error
+        
+        return (returncode, output, error)
+
+# Look ma'! A singleton !
+command = CommandHandler()    
+    
+if __name__ == "__main__":
+    c = CommandHandler()
+    c.verbose = 2
+    #print c.is_auth_needed()
+    
+    print c.sudo_reset()       
+    code, out, err = c.sudo_execute(["head", "/var/log/syslog"], "Pwd FTW !")
+    code, out, err = c.sudo_execute(["head", "/var/log/syslog"], "Pwd FTW !")
+   

=== added file 'build/lib.linux-x86_64-2.6/RapacheCore/VirtualHost.py'
--- build/lib.linux-x86_64-2.6/RapacheCore/VirtualHost.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheCore/VirtualHost.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,379 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import os
+import tempfile
+import re
+from RapacheCore import Configuration
+from RapacheCore.ApacheConf import *
+from RapacheCore.HostsManager import HostsManager
+from RapacheCore import Shell
+
+VHOST_TEMPLATE = """#created for you by Rapache
+<VirtualHost *>
+	#ServerAdmin webmaster@xxxxxxxxxxx
+	ServerName example
+	DocumentRoot /var/www/examplepath
+</VirtualHost>"""
+
+
+def valid_domain_name ( name ):
+    # TODO: fix regular expression 
+    valid = ( re.search( '^[a-zA-Z0-9.-]+$', name ) != None )
+    return valid
+
+def is_denormalized_vhost ( fname ):
+    try:   
+        flink = os.readlink( Configuration.SITES_ENABLED_DIR +"/"+fname )
+        flink = os.path.join(os.path.dirname( Configuration.SITES_AVAILABLE_DIR ), flink)                        
+        #no exceptions ? Means it's a link
+        return True
+    except:
+        return False
+    return False
+def is_not_normalizable( fname):
+     dest = Configuration.SITES_AVAILABLE_DIR + "/" + fname
+     return os.path.exists( dest )
+ 
+def normalize_vhost( fname ):
+    print "Normalizing:", fname
+    orig = Configuration.SITES_ENABLED_DIR + "/" + fname
+    dest = Configuration.SITES_AVAILABLE_DIR + "/" + fname    
+    if ( os.path.exists( dest ) == True ):
+        print fname, "already exists in available dir. not even trying"
+        return False
+    command = ['mv',orig,dest]
+    code, output, error = Shell.command.sudo_execute( command )
+    return ( code == 0 )
+    return  os.path.exists( dest )
+    
+class VirtualHostModel:
+    
+    def __init__(self, name = None, plugin_manager = None):
+        self.defaults = {
+            'enabled' : False
+            , 'name' : None
+            , 'ServerName': None
+            , 'changed' : False            
+            , 'hack_hosts' : False
+            , 'DocumentRoot' : None            
+        }
+        self.data = {}
+        self.parsable = False
+        self.changed = False
+        self.simulation = False
+        
+        self.data = self.defaults
+        if ( name != None ):
+            self.data[ 'name' ] = name
+            self.data[ 'enabled' ] = self.is_enabled()
+            
+        # Init plugin values so the keys exist
+        if plugin_manager:
+        	for plugin in plugin_manager.plugins:
+        		for key in plugin.vhosts_config.keys():
+        				self.data[ key ] = None
+
+    def _search(self, content, regexp ): 
+        content = content.split( "\n" )           
+        for line in content:
+            match = re.search( regexp , line, re.IGNORECASE )            
+            if ( match != None ) :
+                if match != False:
+                    return match            
+        return False
+    
+    def _get_conf_value(self, content, regexp):        
+        match = self._search(content, regexp )
+        if ( match == False or match == None ): return None
+        found_entry = match.groups()                          
+        found_value = found_entry[0]
+        return found_value
+    def load(self, name = False, plugin_manager = None):
+    	if ( name == False ): name = self.data[ 'name' ]
+    	options = {}    	
+        parser = Parser()
+        parser.load(  os.path.join(Configuration.SITES_AVAILABLE_DIR, name) )
+        try:
+            piece = VhostParser( parser )
+        except "VhostNotFound":
+         	self.parsable = False
+         	return False
+        domain_name = piece.get_value( 'ServerName' )
+        if domain_name == None:
+         	self.parsable = False
+         	#return False
+        options[ 'ServerName' ] = domain_name
+        options[ 'ServerAlias' ] = piece.get_options( 'ServerAlias' )
+        print options[ 'ServerAlias' ]
+        options[ 'DocumentRoot' ] = piece.get_value('DocumentRoot')
+        hosts = HostsManager()
+        if ( domain_name == None or hosts.find ( domain_name ) == False ):
+            options['hack_hosts'] = False
+        else:
+            options['hack_hosts'] = True
+        self.parsable = True
+        
+        # Load plugin values
+        if plugin_manager:
+        	for plugin in plugin_manager.plugins:
+        		for key in plugin.vhosts_config.keys():
+        			if plugin.vhosts_config[key] == 1:
+        				options[ key ] = piece.get_options( key )
+        			else:
+        				options[ key ] = piece.get_value( key )
+        
+        self.data.update( options )
+        return True
+            
+        
+    def loaad (self, name = False):
+        print "Loading Vhosts list"
+        try:
+            #reset everything
+            #print "Loading :\t",name
+            if ( name == False ): name = self.data[ 'name' ]
+            self.data = self.defaults   
+            self.data['name'] = name
+            
+            #print "Loading(b) :\t",self.data[ 'name' ]            
+            options = {}
+            content = self.get_source()        
+            #domain_name = self._get_domain_name(content)
+            domain_regexp = r'^\s*ServerName\s+([A-Za-z0-9.\-_]*)'
+            domain_name = self._get_conf_value(content, domain_regexp)
+            options[ 'ServerName' ] = domain_name
+            domain_regexp = domain_name.replace( '.', '\\.' ) #quote for regexp
+            www_regexp = r'^\s*ServerAlias\s*[^#]*\s+www\.'+domain_regexp+'(\s*|$)'
+            folder_regexp = domain_regexp = r'^\s*DocumentRoot\s+(\S+\s*\S+)'
+            
+            #print "Domain Name :\t"+domain_name             
+            if self._search(content, www_regexp ) != None \
+            and self._search(content, www_regexp ) != False  :
+                options[ 'has_www' ] = True
+            else:
+                options[ 'has_www' ] = False 
+    
+            #print "Has www :\t"+str(options[ 'has_www' ])
+                
+            options[ 'DocumentRoot' ] = self._get_conf_value(content, folder_regexp)
+            
+            #print "Document Root :\t"+str( options[ 'DocumentRoot' ] )
+            hosts = HostsManager()
+            if ( hosts.find ( domain_name ) == False ):
+                options['hack_hosts'] = False
+            else:
+                options['hack_hosts'] = True
+            self.parsable = True
+        except:
+            print "Unparsable by me - unsupported"
+            raise "VhostUnparsable"
+            return False
+        self.data.update( options )
+        #print self.data
+        return True
+        
+    def is_enabled ( self ):
+        orig = self.data[ 'name' ]        
+        dirList=os.listdir(  Configuration.SITES_ENABLED_DIR )
+        for fname in dirList:
+            try:                                
+                flink = os.readlink( Configuration.SITES_ENABLED_DIR +"/"+fname )               
+                flink = os.path.join(os.path.dirname( Configuration.SITES_ENABLED_DIR +"/" ), flink)
+                # please note debian features a nice set of
+                # mixed absolute and relative links. FREAKS !
+                # the added "/" is also necessary
+                flink = os.path.normpath(flink)               
+                if ( flink == Configuration.SITES_AVAILABLE_DIR+"/"+orig ):
+                    return True
+            except:
+                pass
+          
+        return False
+   
+    def toggle( self, status ):
+        "status = True|False"
+        if status:
+    	    command = "a2ensite"
+        else :
+    	    command = "a2dissite"        
+        # set new value
+        if self.simulation:
+            print "SIMULATED ",[ command, self.data['name'] ]
+            self.data['enabled'] = status
+        else:
+            Shell.command.sudo_execute( [ command, self.data['name'] ] )
+            self.data['enabled'] = self.is_enabled()
+        self.changed = True
+        
+    def delete( self ):
+        "Deletes a VirtualHost configuration file"
+        if ( self.is_enabled() ): self.toggle( False )
+        Shell.command.sudo_execute( [ 'rm', Configuration.SITES_AVAILABLE_DIR+'/'+self.data['name'] ])
+    def _create_complete_path ( self, complete_path ):
+        print "Attempting to create: " + complete_path
+        tokens = complete_path.split( '/' )
+        del tokens[ 0 ]        
+        path = ''
+        for piece in tokens:
+            path = path + '/' + piece
+            if ( os.path.exists( path ) == False ):
+                try:
+                    Shell.command.sudo_execute( ["mkdir", path] )
+                except:
+                    print "error on creating path"+path
+                    return False                   
+        print "Created path: " + path
+        return True    
+     
+    def get_source ( self ):
+        file = open( Configuration.SITES_AVAILABLE_DIR+'/'+self.data['name'], 'r' )
+        content = file.read()
+        file.close()
+        return content
+    def update ( self, new_options, name ):
+        print "updating virtual host", name
+        #print new_options        
+        
+        old_enabled = self.is_enabled()
+        print "IS ENABLED", old_enabled
+        parser = Parser()
+        parser.load(  Configuration.SITES_AVAILABLE_DIR+'/'+name )
+        piece = VhostParser( parser )
+        old_servername = piece.get_value( 'ServerName' )
+        
+        # Get a bit more dynamic with it
+        for key in new_options.keys():
+            obj = new_options[key]
+            if isinstance(obj, list):
+                piece.set_value(key, '')
+                for opt in obj:
+                    piece.add_option(key, opt )
+            elif isinstance(obj, str):
+                if obj:
+                    piece.set_value(key, obj)
+                else:
+                    piece.remove_value(key)
+        
+        #piece.set_value('ServerAlias',  '' )
+        #for domain in new_options ['ServerAlias']:
+        #    piece.add_option('ServerAlias', domain )
+                                        
+        print "DocumentRoot From",piece.get_value('DocumentRoot' ),"to",new_options['DocumentRoot']
+        piece.set_value('DocumentRoot', new_options['DocumentRoot'] )
+                
+        print "ServerName From",piece.get_value('ServerName' ),"to",new_options['ServerName']
+        piece.set_value('ServerName', new_options['ServerName'] )                
+        complete_path = Configuration.SITES_AVAILABLE_DIR+'/'+ name 
+        
+        print "Writing.."
+        print parser.get_source()
+        self._write( complete_path, parser.get_source() )
+        
+        #if the servername coincides with the configuration filename
+        #we try to stick with the convention
+        new_name = Configuration.SITES_AVAILABLE_DIR + "/"+ new_options['ServerName']
+        old_name = Configuration.SITES_AVAILABLE_DIR + "/"+ old_servername
+        print "old name", old_name
+        print "new name", new_name
+        
+        if old_name != new_name and os.path.exists( new_name ) == False:
+            print "Server name changed, updating conf filename"
+            self.toggle( False )     
+            Shell.command.sudo_execute( [mv, old_name, new_name] )
+            if os.path.exists( new_name ) == True:
+                #success ! we need to reload vhost with the new name
+                self.load( new_options['ServerName'] )
+                #...so we can toogle it on again
+                if old_enabled == True: 
+                    print "Re-activating"
+                    self.toggle( True )
+                else:
+                    print "Skipping activation"
+            else:
+                print "error! not created:", new_name
+        return True
+    def _write(self, complete_path, content ):    
+        tempfilename = tempfile.mktemp()
+        print "creating temporary file "+tempfilename
+        logfile = open( tempfilename , 'w')
+        logfile.write( content )
+        logfile.close()
+        command = ['cp', tempfilename, complete_path ]
+        print "copying tempfile in the appropriate location: ",command
+        Shell.command.sudo_execute( command )
+                
+    def create ( self, new_options ):                
+        
+        options = self.data
+        options.update( new_options )        
+        
+        #as of creation-time name is not expected to be in options
+        options['name'] = options[ 'ServerName' ]
+        complete_path = Configuration.SITES_AVAILABLE_DIR+'/'+options['name']
+        
+        print options               
+        print "Creating virtualhost: "+options['name']
+        print "Folder: "+options['DocumentRoot']
+        
+        if ( os.path.exists( options['DocumentRoot'] ) == False ): 
+            print "Folder "+options['DocumentRoot']+" does not exist"        
+            self._create_complete_path( options['DocumentRoot'] )
+            
+        if ( os.path.exists( options['DocumentRoot'] ) == False ):
+            self.error( "Could not create target folder" ) #TODO fix this
+            return False
+                       
+        if ( valid_domain_name( options['ServerName'] ) == False ):
+            self.error ( 'Bad domain name: '+options['ServerName'] )
+            return False
+        
+        if os.path.exists( complete_path ):
+            raise "VhostExists", 'Virtual host already exists :('
+            #self.error( 'Virtual host already exists :(' )
+            return False        
+        """
+        template = VHOST_TEMPLATE.replace( '||example||', options['ServerName'] )
+        template = template.replace( '||DocumentRoot||', options['DocumentRoot'] )
+        if ( options[ 'has_www' ] ):
+            template = template.replace( '#ServerAlias www', 'ServerAlias www' )        
+        """
+        parser = Parser()
+        parser.set_content_from_string( VHOST_TEMPLATE )
+        piece = VhostParser( parser )
+        piece.set_value('ServerName',  options['ServerName'] ) 
+        piece.set_value('DocumentRoot',  options['DocumentRoot'] ) 
+
+        print "min", piece.min, "max", piece.max
+        #reset previous aliases
+        piece.set_value('ServerAlias',  '' )
+        for domain in options ['ServerAlias']:
+            piece.add_option('ServerAlias', domain )
+        print parser.get_content()
+            
+        self._write( complete_path, "\n".join(parser.get_content() ) )
+          
+        if ( options[ 'hack_hosts' ] ):
+            Shell.command.sudo_execute ( [Configuration.APPPATH+'/hosts-manager', '-a', options['ServerName'] ] )
+            for alias_name in options[ 'ServerAlias' ]:
+            	Shell.command.sudo_execute ( [Configuration.APPPATH+'/hosts-manager', '-a',alias_name ])
+        self.changed = True        
+        self.toggle( True ) #activate by default 
+            
+        return True

=== added file 'build/lib.linux-x86_64-2.6/RapacheCore/__init__.py'
=== added directory 'build/lib.linux-x86_64-2.6/RapacheGtk'
=== added file 'build/lib.linux-x86_64-2.6/RapacheGtk/CheckListView.py'
--- build/lib.linux-x86_64-2.6/RapacheGtk/CheckListView.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheGtk/CheckListView.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,123 @@
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import gobject
+
+(
+    COLUMN_FIXED,
+    COLUMN_SEVERITY,
+    COLUMN_MARKUP
+) = range(3)
+from RapacheCore import Configuration
+import RapacheCore.Observer
+from RapacheGtk.EventDispatcher import Master
+
+class CheckListView (gtk.TreeView ):
+    """Nice list with icons and checkboxes"""
+    def __init__ (self, *args, **kwargs):                
+        super (CheckListView, self).__init__ (*args, **kwargs)
+        
+        self.toggled_callback = None
+        self.selected_callback = None
+        self.icon_callback = None
+        
+        self.Observable = RapacheCore.Observer.Observable()
+        Master.register(self)
+        
+        self.column_checkbox = None
+        self.column_description = None
+        self.column_icon = None
+        
+        self.__add_columns()
+
+        self.set_headers_visible( False )
+        self.set_rules_hint(True)
+        self.set_search_column(COLUMN_SEVERITY)
+        
+    #----decorating observer    
+    def register (self, *args, **kwargs): return self.Observable.register(*args, **kwargs)
+    def unregister (self, *args, **kwargs): return self.Observable.unregister(*args, **kwargs)
+    def handle_event (self, *args, **kwargs): return self.Observable.handle_event(*args, **kwargs)
+    def raise_event (self, *args, **kwargs): return self.Observable.raise_event(*args, **kwargs)
+    
+    def load (self):
+        raise "AbstractMethod", "Please override this"
+    
+    def _reset_model (self):
+        lstore = self.get_model()
+        if ( lstore == None ):
+            lstore = self._default_model()
+            self.set_model( lstore )
+        else:
+            lstore.clear()
+        return lstore
+    def _default_model (self):
+        lstore = gtk.ListStore(
+                gobject.TYPE_BOOLEAN,
+                gobject.TYPE_STRING,
+                gobject.TYPE_STRING)
+        return lstore
+    
+    def __toggled(self, *args, **kwargs):
+        if self.toggled_callback != None:
+            self.toggled_callback( *args, **kwargs )
+    def __selected(self, *args, **kwargs):
+        if self.selected_callback != None:
+            self.selected_callback( *args, **kwargs )
+    def __icon_requested(self, *args, **kwargs):
+        if self.icon_callback != None:
+            self.icon_callback( *args, **kwargs )       
+                                  
+    def __add_columns(self):
+        #model = self.get_model()
+        # column for fixed toggles
+        renderer = gtk.CellRendererToggle()
+        renderer.connect('toggled', self.__toggled, self)
+        self.column_checkbox = gtk.TreeViewColumn('Enabled', renderer, active=COLUMN_FIXED)
+        self.column_checkbox.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        self.column_checkbox.set_fixed_width(40)
+        self.append_column(self.column_checkbox)
+
+        self.column_icon = gtk.TreeViewColumn()
+        cellRenderer = gtk.CellRendererPixbuf()
+        self.column_icon.pack_start(cellRenderer, expand = False)
+        self.column_icon.set_cell_data_func(cellRenderer, self.__icon_requested )
+        self.append_column(self.column_icon)        
+   
+        self.column_description = gtk.TreeViewColumn('Description', gtk.CellRendererText(),
+                                     markup=COLUMN_MARKUP)
+        self.column_description.set_sort_column_id(COLUMN_MARKUP)
+        self.append_column(self.column_description)
+        self.get_selection().connect("changed", self.__selected )
+        
+    def get_selected_line( self ):
+        #try:
+        selection = self.get_selection()
+        #print '==>', self.get_selected()
+        #print selection.get_selected_rows()[1]
+        try:
+            rows = selection.get_selected_rows()[1][0]
+            num_row = rows[0]
+            model = self.get_model()
+            name = model[ num_row ][1]
+        except IndexError:
+            return None
+        return name
+        #except:
+        #    return None
+
+gobject.type_register (CheckListView)
\ No newline at end of file

=== added file 'build/lib.linux-x86_64-2.6/RapacheGtk/ConfirmationWindow.py'
--- build/lib.linux-x86_64-2.6/RapacheGtk/ConfirmationWindow.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheGtk/ConfirmationWindow.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import re
+
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+    
+try:
+    from RapacheCore import Configuration
+except:
+    if __name__ != "__main__":
+        sys.exit(1)
+
+import os
+
+        
+class ConfirmationWindow:
+    
+    def __init__ ( self, parent = None):
+           
+        self.parent = parent
+        self.title = None
+        self.question = None
+        self.return_value = None
+        
+        gladefile = os.path.join(Configuration.GLADEPATH, "confirmation.glade")
+        wtree = gtk.glade.XML(gladefile)
+        
+        self.window = wtree.get_widget("confirmation_window")
+        self.ok_button = wtree.get_widget("ok_button")
+        self.cancel_button = wtree.get_widget("cancel_button")
+        self.question_label = wtree.get_widget("question_label")
+        signals = {
+            "on_ok_button_clicked"       : self.on_ok_button_clicked,
+            "on_cancel_button_clicked"     : self.on_cancel_button_clicked
+        }
+        wtree.signal_autoconnect(signals)
+                
+        # add on destroy to quit loop
+        self.window.connect("destroy", self.on_destroy)
+                
+    def run(self):
+        if self.title: self.window.set_title ( self.title )
+        if self.question: self.question_label.set_text( self.question )
+        
+        self.window.show()           
+        gtk.main()
+
+    def on_destroy(self, widget, data=None):
+        gtk.main_quit()
+
+    def on_ok_button_clicked(self, widget):
+        self.return_value = True
+        self.window.destroy()
+    def on_cancel_button_clicked(self, widget):
+        self.return_value = False
+        self.window.destroy()
+
+def ask_confirmation ( question = None, title = None):
+    win = ConfirmationWindow()
+    win.title = title
+    win.question = question    
+    win.run()
+    answer = win.return_value
+    print "Question: ", question
+    print "Answer: ", answer
+    return answer
+    
+    
+if __name__ == "__main__":
+    class Configuration:
+        GLADEPATH = '../Glade'
+    value = ask_confirmation( 'did you solve bug #1 ?', 'bug confirmation')
+    print '================='
+    print value
+    
+    
\ No newline at end of file

=== added file 'build/lib.linux-x86_64-2.6/RapacheGtk/DesktopEnvironment.py'
--- build/lib.linux-x86_64-2.6/RapacheGtk/DesktopEnvironment.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheGtk/DesktopEnvironment.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,44 @@
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import subprocess
+import os
+from RapacheCore import Shell
+
+"""abstracts Desktop Environment's specific operation."""
+# TODO: refactor this into a factory to support more than a Desktop Environment easily
+#
+# care should be taken with userid, we don't want root priviledges when they're not needed
+
+
+# Grabbed from Ubuntu's UpdateManager (ChangelogViewer.py)    
+#  Copyright (c) 2006 Sebastian Heinlein
+#                2007 Canonical    
+# TODO: move this into an utility module        
+def open_url(url):
+    """Opens the specified URL in a browser"""
+    # Find an appropiate browser
+    if os.path.exists('/usr/bin/gnome-open'):
+        command = ['gnome-open', url]
+    else:
+        command = ['x-www-browser', url]
+    # Avoid to run the browser as user root
+    if os.getuid() == 0 and os.environ.has_key('SUDO_USER'):
+        command = ['sudo', '-u', os.environ['SUDO_USER']] + command
+    subprocess.Popen(command)
+# TODO: find out how to open nautilus in background
+def open_dir( path):
+    Shell.command.sudo_execute ( ['nautilus',path, '--no-desktop']  )

=== added file 'build/lib.linux-x86_64-2.6/RapacheGtk/EditDomainNameGui.py'
--- build/lib.linux-x86_64-2.6/RapacheGtk/EditDomainNameGui.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheGtk/EditDomainNameGui.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import re
+import os
+
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+
+from RapacheCore.VirtualHost import *
+from RapacheGtk import GuiUtils
+        
+class EditDomainNameWindow:
+
+	def __init__ ( self, domain = ""):
+		self.return_value = None
+		
+		gladefile = os.path.join(Configuration.GLADEPATH, "edit_domain_name.glade")
+		wtree = gtk.glade.XML(gladefile)
+		
+		self.window = wtree.get_widget("dialog_edit_domain_name")
+        	self.entry_domain = wtree.get_widget("entry_domain")
+        	self.label_heading = wtree.get_widget("label_heading")
+        	self.image_icon = wtree.get_widget("image_icon")
+
+        	signals = {
+			"on_button_ok_clicked"        	: self.on_button_ok_clicked,
+			"on_button_cancel_clicked"      : self.on_button_cancel_clicked
+		}
+		wtree.signal_autoconnect(signals)
+		
+		# add on destroy to quit loop
+		self.window.connect("destroy", self.on_destroy)
+		
+		if domain:
+			self.entry_domain.set_text( domain )
+        
+        def run(self):
+        	self.window.show()
+        	self.entry_domain.select_region(0,-1)
+        	gtk.main()
+         	
+        	return self.return_value
+
+        def on_destroy(self, widget, data=None):
+		gtk.main_quit()
+
+	def on_button_ok_clicked(self, widget):
+		self.return_value = self.entry_domain.get_text()
+		self.window.destroy()
+        	return         	
+        	
+	def on_button_cancel_clicked(self, widget):
+		self.window.destroy()
+        	return    
+        	    	

=== added file 'build/lib.linux-x86_64-2.6/RapacheGtk/EventDispatcher.py'
--- build/lib.linux-x86_64-2.6/RapacheGtk/EventDispatcher.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheGtk/EventDispatcher.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,19 @@
+import RapacheCore.Observer
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Master = RapacheCore.Observer.PollyObserver()
\ No newline at end of file

=== added file 'build/lib.linux-x86_64-2.6/RapacheGtk/GuiUtils.py'
--- build/lib.linux-x86_64-2.6/RapacheGtk/GuiUtils.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheGtk/GuiUtils.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,53 @@
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import gtksourceview2
+import pango
+from RapacheCore import Configuration
+
+def style_as_tooltip( obj ):
+    pw = gtk.Window(gtk.WINDOW_POPUP)
+    pw.set_name('gtk-tooltip')
+    pw.ensure_style()
+    obj.set_style(pw.get_style())
+    obj.connect('expose-event', paint)
+    
+def paint(box, event):
+        box.style.paint_flat_box(box.window, gtk.STATE_NORMAL, gtk.SHADOW_OUT, None, box, "tooltip", box.allocation.x+1, box.allocation.y+1, box.allocation.width-2, box.allocation.height-2)
+
+def change_button_label ( button, new_label ):
+        """Changes the label of a button"""
+        button.show()
+        alignment = button.get_children()[0]
+        hbox = alignment.get_children()[0]
+        image, label = hbox.get_children()
+        label.set_text( new_label )
+
+def new_apache_sourceview():
+    bufferS = gtksourceview2.Buffer()
+    manager = gtksourceview2.LanguageManager()
+    
+    #language = manager.get_language_from_mime_type("text/xml")
+    manager.set_search_path( [ Configuration.GLADEPATH ] + manager.get_search_path() )
+    language = manager.get_language('apache')
+    bufferS.set_language(language)
+    bufferS.set_highlight_syntax(True)
+    sourceview = gtksourceview2.View(bufferS)
+    sourceview.set_show_line_numbers(True)
+    #TODO sniff gnome default monospace font
+    sourceview.modify_font(pango.FontDescription("monospace 10"))
+    return sourceview
\ No newline at end of file

=== added file 'build/lib.linux-x86_64-2.6/RapacheGtk/ModuleGui.py'
--- build/lib.linux-x86_64-2.6/RapacheGtk/ModuleGui.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheGtk/ModuleGui.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,139 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+""".
+Issues with the new window:
+    - self.parent doesn't work
+    - onblur doesn't trigger when pressing Return
+    - changing a domain name doesn't change subdomains
+    - empty server aliases shuoldn't be managed
+ALSO:
+    - please implement a delete directive func in the parser
+    - move denorm. vhosts in another tab
+    - merge with Qense warning window
+"""
+
+import sys
+import re
+
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+
+import os
+import pango
+import tempfile
+import traceback
+import RapacheGtk.GuiUtils
+from RapacheCore.Module import *
+from RapacheGtk import GuiUtils
+import RapacheGtk.DesktopEnvironment as Desktop
+
+
+def open_module_doc( name ):
+        if ( name == None ): return False
+        url = "http://httpd.apache.org/docs/2.2/mod/mod_%s.html"; % name
+        Desktop.open_url( url )
+        
+class ModuleWindow:
+    
+    def __init__ ( self, parent = None):
+           
+        self.module = None
+        self.create_new = True
+        self.parent = parent
+        
+        gladefile = os.path.join(Configuration.GLADEPATH, "edit_module.glade")
+        wtree = gtk.glade.XML(gladefile)
+        
+        self.window = wtree.get_widget("dialog_edit_module")
+        #self.text_view_module_conf = wtree.get_widget("text_view_module_conf")
+        self.notebook = wtree.get_widget("notebook")
+        self.button_save = wtree.get_widget("button_save")
+        self.error_area = wtree.get_widget("error_area")
+        self.module_doc_button = wtree.get_widget("module_doc_button")
+        
+        signals = {
+            "on_button_save_clicked"            : self.on_button_save_clicked,
+            "on_button_cancel_clicked"          : self.on_button_cancel_clicked,
+            "on_module_doc_button_clicked"      : self.on_module_doc_button_clicked
+        }
+        wtree.signal_autoconnect(signals)            
+        # add on destroy to quit loop
+        self.window.connect("destroy", self.on_destroy)
+        
+        self.text_view_module_conf = GuiUtils.new_apache_sourceview()        
+        self.text_view_module_conf.show()
+        wtree.get_widget("text_view_module_conf_area").add(self.text_view_module_conf)
+        
+        GuiUtils.change_button_label( self.module_doc_button, 'Documentation' )
+        GuiUtils.style_as_tooltip( self.error_area )
+    def run(self):
+        self.window.show()           
+        gtk.main()
+
+    def load (self, name ):
+        self.window.set_title(name)
+        self.module = ModuleModel ( name )
+        #self.module.load()
+        buf = self.text_view_module_conf.get_buffer()
+        buf.set_text( self.module.get_configuration() )
+        
+         # Load UI Plugins
+        for plugin in self.parent.plugin_manager.plugins:
+        	if plugin.module == name:
+			try:
+				print "Loading plugin " + name
+				plugin.load_module_properties(self.notebook, self.module)
+			except Exception:
+				traceback.print_exc(file=sys.stdout)
+
+    def on_destroy(self, widget, data=None):
+        gtk.main_quit()
+
+    def on_button_save_clicked(self, widget):
+        
+        name = self.module.data['name']
+        print "Current name:", name
+        buff = self.text_view_module_conf.get_buffer()
+        text = buff.get_text(buff.get_start_iter(), buff.get_end_iter())
+
+        mod = ModuleModel( name )
+        mod.save_configuration( text )
+        
+        #self.parent.refresh_vhosts()
+        self.parent.please_restart()
+        self.window.destroy()
+                               
+    def on_button_cancel_clicked(self, widget):
+        self.window.destroy()
+        return    
+    def on_module_doc_button_clicked (self, widget ):
+        name = self.module.data['name']
+        open_module_doc(name)
+    def show_error ( self, message ):
+        
+        self.xml.get_widget( 'message_text' ).set_label( '<b>'+message+'</b>' )
+        self.xml.get_widget( 'message_container' ).show()

=== added file 'build/lib.linux-x86_64-2.6/RapacheGtk/RapacheGui.py'
--- build/lib.linux-x86_64-2.6/RapacheGtk/RapacheGui.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheGtk/RapacheGui.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,294 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#TODO throw appropriate exceptions (bug: vhost already exist displays only 
+# after actually trying to create it's dir. check before )
+
+#TODO read ERRORLEVEL from command line operations
+#TODO stop operation if gksudo fails
+#TODO check for sites-enabled-only sites and normalize them
+
+#TODO delete-tarantella: hosts deletion & confirmation
+
+#TODO refuse to edit complex vhosts ( done ? )
+
+import gnome.ui
+import gobject
+import gtk
+import os
+import re
+(
+    COLUMN_FIXED,
+    COLUMN_SEVERITY,
+    COLUMN_MARKUP
+) = range(3)
+
+
+from RapacheGtk.VirtualHostGui import VirtualHostWindow
+from RapacheGtk.ModuleGui import ModuleWindow
+from RapacheCore.PluginManager import PluginManager
+from RapacheGtk.ModuleGui import open_module_doc
+from RapacheCore.VirtualHost import *
+from RapacheGtk import ConfirmationWindow
+from RapacheGtk import GuiUtils
+from RapacheCore import Shell
+import VhostsTreeView
+import RapacheCore.Observer
+from RapacheGtk.EventDispatcher import Master
+import subprocess
+import RapacheGtk.DesktopEnvironment as Desktop
+
+data = \
+[(False, "Loading", "please wait" )]
+
+APPNAME="Rapache"
+APPVERSION="0.6"
+
+
+class MainWindow( RapacheCore.Observer.Observable ) :
+    """This is an Hello World Rapacheefication application"""
+    
+    def __init__(self, *args, **kwargs):
+        super (MainWindow, self).__init__ (*args, **kwargs)
+        Master.register(self)
+
+        self.denormalized_virtual_hosts = {}
+        self.plugin_manager = PluginManager()
+        gnome.init(APPNAME, APPVERSION)
+        self.gladefile = Configuration.GLADEPATH + "/" + "main.glade"  
+        self.xml = gtk.glade.XML(self.gladefile)         
+        #Create our dictionary and connect it
+        dic = { "new_button_clicked" : self.new_button_clicked,
+            "on_MainWindow_destroy" : self.quit ,
+            "please_restart" : self.restart_apache ,            
+            "on_delete" : self.delete_button_clicked,
+            "edit_button_clicked" : self.edit_button_clicked,
+            "edit_module_button_clicked" : self.edit_module_button_clicked,
+            "browse_sites_available" : self.browse_sites_available,
+            "fix_vhosts_clicked" : self.fix_vhosts,
+            "surf_this_button_clicked" : self.surf_this,
+            "browse_button_clicked" : self.browse_this,
+            "about_clicked" : self.display_about,
+            "open_doc_button_clicked" : self.open_doc_button_clicked,
+            "on_button_hide_warning_clicked" : self.on_button_hide_warning_clicked,
+            "quit" : self.quit }
+        gtk.window_set_default_icon(self.xml.get_widget("MainWindow").get_icon())
+        self.xml.signal_autoconnect(dic)
+        GuiUtils.change_button_label ( self.xml.get_widget( 'restart_apache' ), "Restart Apache" )
+        GuiUtils.change_button_label ( self.xml.get_widget( 'fix_vhosts' ), "Fix Virtual Hosts" )
+        #hereby we create lists
+        self.create_vhost_list()
+        self.create_modules_list()
+        #hereby we fill them
+        self.refresh_lists()
+        
+        GuiUtils.style_as_tooltip( self.xml.get_widget( 'restart_apache_notice' ) )
+        GuiUtils.style_as_tooltip( self.xml.get_widget( 'unnormalized_notice' ) )    
+        
+    def on_button_hide_warning_clicked(self, widget):
+        self.xml.get_widget( 'restart_apache_notice' ).hide()
+        
+    def handle_event(self, event ):
+        if event.name == 'please_restart_apache':
+            self.please_restart()
+            return
+        if event.name == 'please_reload_lists':
+            self.load_lists()
+            return
+    def browse_sites_available(self, widget):
+        Desktop.open_dir( Configuration.SITES_AVAILABLE_DIR )
+        return
+    
+    def new_button_clicked(self, widget):
+        new_vhost_window = VirtualHostWindow ( self )
+        #new_vhost_window.load()
+        new_vhost_window.run()
+    def edit_button_clicked(self, widget, notused = None, notused2 = None):         
+        name = self.vhosts_treeview.get_selected_line()
+        print "edit button clicked on:" + name          
+        if ( self.is_vhost_editable( name ) == False ): return False
+        new_vhost_window = VirtualHostWindow ( self )
+        new_vhost_window.load( name )
+        new_vhost_window.run()    
+    def delete_button_clicked( self, widget ):
+        name = self.vhosts_treeview.get_selected_line()
+        if ( self.is_vhost_editable( name ) == False ): return False
+        if ( name == None ): return False
+        result = ConfirmationWindow.ask_confirmation(           
+            "You are about to delete the following domain: \n\n"+name+"\n\nData won't be recoverable. Proceed ?"
+            ,'VirtualHost deletion' )
+        if ( result != True ): return False
+        site = VirtualHostModel( name )
+        site.delete()
+        self.vhosts_treeview.load()
+        self.please_restart()
+    def edit_module_button_clicked(self, widget, notused = None, notused2 = None):
+        name = self.modules_treeview.get_selected_line()
+        if ( self.is_module_editable( name ) == False ): return False
+        print "module edit button clicked on:", name          
+        module_window = ModuleWindow ( self )
+        module_window.load( name )
+        module_window.run()        
+    def quit (self, widget):
+        print 'quitting'
+        gtk.main_quit()
+        exit()
+    
+    def create_vhost_list(self ):
+        #print parent
+        #sw = gtk.ScrolledWindow()
+        sw = self.xml.get_widget( 'vhosts_scroll_box' )      
+        # create virtualhosts treeview
+        treeview = VhostsTreeView.VhostsTreeView()
+        treeview.selected_callback = self.row_selected
+        treeview.connect_after("row-activated", self.edit_button_clicked )
+        self.vhosts_treeview = treeview        
+        self.xml.get_widget( 'vhost_container' ).add(treeview)        
+        self.xml.get_widget( 'vhost_container' ).reorder_child( treeview, 0)
+
+        sw.set_shadow_type(gtk.SHADOW_NONE)
+        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        sw.set_shadow_type(gtk.SHADOW_NONE)
+        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        
+        # create denormalized vhosts.
+        # We check for conf files only present in /etc/apache2/sites-enabled,
+        # display them as a separate list and offer user to normalize them
+        # moving them in /etc/apache2/sites-available and linking them back
+        # from /etc/apache2/sites-enabled
+        
+        denormalized_treeview = VhostsTreeView.DenormalizedVhostsTreeView()
+        self.denormalized_treeview = denormalized_treeview        
+        self.xml.get_widget( 'problems_area' ).add(denormalized_treeview)        
+        self.xml.get_widget( 'problems_area' ).reorder_child( denormalized_treeview, 2)
+        denormalized_treeview.set_sensitive( False )
+        denormalized_treeview.show()
+        sw.show_all()
+        #hidden by default
+        self.xml.get_widget( 'unnormalized_notice' ).hide_all()
+    
+    def create_modules_list(self ):
+        sw = self.xml.get_widget( 'modules_scroll_box' )
+        # create virtualhosts treeview
+        treeview = VhostsTreeView.ModulesTreeView()
+        treeview.connect_after("row-activated", self.edit_module_button_clicked )
+        treeview.selected_callback = self.module_row_selected
+        self.modules_treeview = treeview        
+        self.xml.get_widget( 'modules_container' ).add(treeview)        
+        self.xml.get_widget( 'modules_container' ).reorder_child( treeview, 0)
+        sw.set_shadow_type(gtk.SHADOW_NONE)
+        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        sw.set_shadow_type(gtk.SHADOW_NONE)
+        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        sw.show_all()
+                      
+    def refresh_vhosts ( self ):
+        print "reloading vhosts.."            
+        self.vhosts_treeview.load()
+    def refresh_denormalized_vhosts (self):
+        self.denormalized_treeview.load()
+        if ( len( self.denormalized_treeview.items ) > 0 ):
+            self.xml.get_widget( 'unnormalized_notice' ).show_all()
+            self.xml.get_widget( 'notebook' ).get_nth_page( 2 ).show()
+        else:
+            self.xml.get_widget( 'unnormalized_notice' ).hide_all()
+            self.xml.get_widget( 'notebook' ).get_nth_page( 2 ).hide()
+    def refresh_modules (self):    
+        print "reloading modules.."            
+        self.modules_treeview.load()
+    def refresh_lists (self):
+        self.refresh_vhosts()
+        self.refresh_modules()
+        self.refresh_denormalized_vhosts()
+    def please_restart ( self ):
+        self.xml.get_widget( 'restart_apache_notice' ).show()
+    def restart_apache ( self, widget ):
+        print "Restarting apache on user's request"
+        Shell.command.sudo_execute( ['/etc/init.d/apache2', 'stop'] )
+        Shell.command.sudo_execute( ['/etc/init.d/apache2', 'start'] )
+        self.xml.get_widget( 'restart_apache_notice' ).hide()
+        self.refresh_lists()
+    def is_vhost_editable (self, name):
+        return name != 'default'
+    def is_module_editable (self, name):
+        editable = False
+        if name:
+            mod = self.modules_treeview.items[ name+".load" ]
+            editable = mod.data[ 'configurable' ]
+        return editable
+    def row_selected( self, widget ):
+        name = self.vhosts_treeview.get_selected_line()
+        if ( name == None ):
+            self.xml.get_widget( 'delete_button' ).set_sensitive( False )
+            self.xml.get_widget( 'edit_button' ).set_sensitive( False )
+            self.xml.get_widget( 'open_in_browser_button' ).set_sensitive( False )
+        else:
+            editable = self.is_vhost_editable( name )
+            self.xml.get_widget( 'delete_button' ).set_sensitive( editable )
+            self.xml.get_widget( 'edit_button' ).set_sensitive( editable )
+            surfable =  self.get_current_vhost_directive( 'ServerName' ) != None
+            self.xml.get_widget( 'surf_this_button' ).set_sensitive( surfable )
+            browsable =  self.get_current_vhost_directive( 'DocumentRoot' ) != None
+            self.xml.get_widget( 'browse_button' ).set_sensitive( browsable )
+    def module_row_selected( self, widget):
+        name = self.modules_treeview.get_selected_line()
+        editable = self.is_module_editable(name)
+        self.xml.get_widget( 'edit_module_button' ).set_sensitive( editable )
+        if name != None: self.xml.get_widget( 'open_doc_button' ).set_sensitive( True )
+    # TODO: open doc only for apache2.2 own modules, not third-party (eg mod_php5)
+    # TODO: sniff apache version, don't hardcode it
+    def open_doc_button_clicked( self, widget ):
+        name = self.modules_treeview.get_selected_line()
+        if ( name == None ): return False
+        open_module_doc(name)
+        
+    def fix_vhosts(self, widget):
+        items = self.denormalized_treeview.get_items()
+        for name in items:
+            normalize_vhost( name )
+        #since they were in the enabled, let's enabl'em again
+        for name in items:
+            site = VirtualHostModel( name )
+            site.toggle(True)            
+        self.refresh_vhosts()
+        self.refresh_denormalized_vhosts()
+    def get_current_vhost_directive (self, directive_name ):
+        name = self.vhosts_treeview.get_selected_line()
+        if ( name == None ): return None
+        return self.vhosts_treeview.items[ name ].data[ directive_name ]
+    def surf_this(self, widget):
+        name = self.vhosts_treeview.get_selected_line()
+        if name == 'default':
+            server_name = 'localhost'
+        else:
+            server_name = self.get_current_vhost_directive( 'ServerName' )
+        if ( server_name ): Desktop.open_url( "http://"; + server_name )
+    def browse_this(self, widget):
+        document_root = self.get_current_vhost_directive( 'DocumentRoot' )
+        Desktop.open_dir( document_root )
+        
+
+    def display_about (self, widget):
+        dialog = gtk.AboutDialog()
+        dialog.set_name( APPNAME )
+        dialog.set_version( APPVERSION )
+        dialog.set_authors( ["Rapache Developers\nhttps://launchpad.net/~rapache-devel";] )
+        dialog.set_comments('Rapache is an Apache configurator for Ubuntu/Gnome systems')
+        dialog.set_website('http://launchpad.net/rapache')
+        dialog.run()
+        dialog.destroy()

=== added file 'build/lib.linux-x86_64-2.6/RapacheGtk/VhostsTreeView.py'
--- build/lib.linux-x86_64-2.6/RapacheGtk/VhostsTreeView.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheGtk/VhostsTreeView.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,237 @@
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import gobject
+from CheckListView import *
+import os
+import re
+from RapacheCore.VirtualHost import *
+from RapacheCore import Module
+from RapacheCore import Configuration
+
+class ConfFilesTreeView( CheckListView ):
+    def __init__ (self, *args, **kwargs):
+        super (ConfFilesTreeView, self).__init__ (*args, **kwargs)
+        self.items = {}
+    def _blacklisted ( self, fname ):
+        if re.match( '.*[~]\s*$', fname ) != None : return True
+        if re.match( '.*.swp$', fname ) != None : return True
+        return False 
+    def is_empty (self):
+        return len( self.items ) == 0
+    def get_items(self):
+        return self.items
+gobject.type_register (ConfFilesTreeView)
+
+
+class VhostsTreeView ( ConfFilesTreeView ):
+    def __init__ (self, *args, **kwargs):
+        super (VhostsTreeView, self).__init__ (*args, **kwargs)
+        self.icon_callback = self.__get_row_icon  
+        self.toggled_callback = self.__fixed_toggled
+    
+    
+    def load(self):
+        self.items = {}
+        site_template = "<b><big>%s</big></b>\n<small>DocumentRoot: %s</small>"
+        site_unparsable_template = "<b><big>%s</big></b>\n<small><i>Further information not available</i></small>"
+        
+        lstore = self._reset_model()
+            
+        data = []          
+        dirList=os.listdir( Configuration.SITES_AVAILABLE_DIR )
+        dirList = [x for x in dirList if self._blacklisted( x ) == False ]            
+        for fname in  dirList :                        
+            site = VirtualHostModel( fname )
+            try:
+                site.load()
+            except "VhostUnparsable":
+                pass
+            self.items[ fname ] = site
+            site = None
+                            
+        for idx in sorted( self.items ):
+            site = self.items[ idx ]
+            if ( site.parsable ):
+                markup = site_template \
+                % ( site.data['name'] , site.data[ 'DocumentRoot' ] )
+            else:
+                markup = site_unparsable_template % site.data['name']
+            iter = lstore.append()
+            lstore.set(iter,
+                COLUMN_FIXED, site.data['enabled'],
+                COLUMN_SEVERITY, site.data['name'],
+                COLUMN_MARKUP, markup )
+
+    #TODO: warning ! This function get's called even on mousehover
+    #      check for a way to optimize it
+    def __get_row_icon (self, column, cell, model, iter):
+        """ Provides the icon for a virtual host looking up it's favicon"""        
+        """node = model.get_value(iter, MODEL_FIELD_NODE)
+        pixbuf = getPixbufForNode(node)
+        cell.set_property('pixbuf', pixbuf)"""                
+        favicon = os.path.join( Configuration.GLADEPATH, 'browser.png' )
+        fname = model.get_value(iter, COLUMN_SEVERITY )
+        site = self.items[ fname ]
+        if site.data['DocumentRoot'] != None:
+            custom_favicon = os.path.join(os.path.dirname( site.data['DocumentRoot']+"/" ), "favicon.ico")                                                    
+            if ( os.path.exists( custom_favicon ) ): favicon = custom_favicon
+            
+        pixbuf = gtk.gdk.pixbuf_new_from_file( favicon )
+        cell.set_property("pixbuf", pixbuf)
+        
+    def __fixed_toggled(self, cell, path, treeview):        
+        # get toggled iter        
+        model = treeview.get_model()
+        iter = model.get_iter((int(path),))
+        fixed = model.get_value(iter, COLUMN_FIXED)
+        name = model.get_value(iter, COLUMN_SEVERITY)
+
+        fixed = not fixed        
+        if fixed:
+            Shell.command.sudo_execute ( [Configuration.APPPATH+'/hosts-manager', '-a',name])
+        else :
+            Shell.command.sudo_execute ( [Configuration.APPPATH+'/hosts-manager', '-r',name])
+        # set new value        
+        site = VirtualHostModel( name )
+        site.toggle( fixed )
+        model.set(iter, COLUMN_FIXED, site.data['enabled'] )        
+        if ( site.changed ):
+            self.raise_event( 'please_restart_apache' )                
+gobject.type_register (VhostsTreeView)
+
+class DenormalizedVhostsTreeView ( ConfFilesTreeView ):
+    def __init__ (self, *args, **kwargs):
+        super (DenormalizedVhostsTreeView, self).__init__ (*args, **kwargs)
+        print self.column_checkbox, self.column_description, self.column_icon
+        self.column_checkbox.set_visible( False )
+        self.column_icon.get_cell_renderers()[0].set_property( 'stock-id',  gtk.STOCK_DIALOG_WARNING )        
+    def load(self):    
+        self.items = {}
+        site_template = "<b><big>%s</big></b>"        
+        lstore = self._reset_model()
+        
+        data = []  
+        dirList=os.listdir( Configuration.SITES_ENABLED_DIR )
+        dirList = [x for x in dirList if self._blacklisted( x ) == False ]
+        dirList = [x for x in dirList if is_denormalized_vhost( x ) == False ]                   
+        for fname in  dirList :
+            site = VirtualHostModel( fname )                        
+            self.items[ fname ] = site
+            site = None
+
+        for idx in sorted( self.items ):            
+            site = self.items[ idx ]
+            normalizable = not is_not_normalizable(site.data['name'])
+            markup = site_template % site.data['name']
+            if ( normalizable == False ):
+                markup = markup + " CANNOT FIX"
+            iter = lstore.append()
+            lstore.set(iter,
+                COLUMN_FIXED, normalizable,
+                COLUMN_SEVERITY, site.data['name'],
+                COLUMN_MARKUP, markup 
+                )
+    def toggled_callback(self, *args, **kwargs):
+        pass
+gobject.type_register (DenormalizedVhostsTreeView )
+
+class ModulesTreeView ( ConfFilesTreeView ):
+    def __init__ (self, *args, **kwargs):
+        super (ModulesTreeView, self).__init__ (*args, **kwargs)
+        
+        icon_file_name = os.path.join( Configuration.GLADEPATH , "modules.png")
+        pixbuf = gtk.gdk.pixbuf_new_from_file( icon_file_name )
+        
+        self.column_icon.get_cell_renderers()[0].set_property('pixbuf', pixbuf) 
+        self.toggled_callback = self.__fixed_toggled
+        self.selected_callback = self.__selected
+        self.column_description.get_cell_renderers()[0].set_property('wrap-mode', gtk.WRAP_WORD)
+        self.column_description.get_cell_renderers()[0].set_property('wrap-width', 400)
+    def __selected(self, *args, **kwargs ):
+        print "MODULE NAME:", self.get_selected_line()
+        print "DEPENDANTS: ", Module.get_module_dependants(self.get_selected_line(), self.items)
+    def load(self):
+        self.items = {}
+        mod_template = "<b><big>%s</big></b>"
+        mod_unparsable_template = "<b><big>%s</big></b>\n<small><i>Further information not available</i></small>"
+        lstore = self._reset_model()
+        data = []  
+        
+        """dirList=os.listdir( Configuration.MODS_AVAILABLE_DIR )
+        dirList = [x for x in dirList if self._blacklisted( x ) == False ]            
+        for fname in  dirList :                        
+            mod = Module.ModuleModel( fname )
+            try:
+                mod.load()
+            except "VhostUnparsable":
+                pass
+            self.items[ fname ] = mod
+            mod = None
+        """
+        self.items = Module.module_list()
+
+        for idx in sorted( self.items ):
+            mod = self.items[ idx ]
+            if ( mod.parsable ):
+                markup = mod_template \
+                % ( mod.data['name'] ) #, mod.data[ 'DocumentRoot' ] )
+                markup += "\n<small>%s</small>" % mod.data[ 'description' ]
+                if len( mod.data[ 'dependancies' ] ) > 0:
+                    markup += "\n<small><b>%s</b></small>" % ( "Dependencies: " + \
+                    ", ".join( mod.data[ 'dependancies' ] ) )
+                else:
+                    markup += "\n<small><i>No dependencies</i></small>"
+            else:
+                markup = mod_unparsable_template % mod.data['name']
+            iter = lstore.append()
+            lstore.set(iter,
+                COLUMN_FIXED, mod.data['enabled'],
+                COLUMN_SEVERITY, mod.data['name'],
+                COLUMN_MARKUP, markup )
+            
+    def __fixed_toggled(self, cell, path, treeview):        
+        # get toggled iter        
+        model = treeview.get_model()
+        iter = model.get_iter((int(path),))
+        fixed = model.get_value(iter, COLUMN_FIXED)
+        name = model.get_value(iter, COLUMN_SEVERITY)
+        fixed = not fixed        
+        # set new value        
+        mod = Module.ModuleModel( name )
+        mod.toggle( fixed )
+        model.set(iter, COLUMN_FIXED, mod.data['enabled'] )
+        if ( mod.changed ):
+            self.raise_event( 'please_restart_apache' ) 
+        self.raise_event( 'please_reload_lists', {}, True ) 
+    #TODO: warning ! This function get's called even on mousehover
+    #      check for a way to optimize it
+    def __get_row_icon (self, column, cell, model, iter):
+        """ Provides the icon for a module"""        
+        """node = model.get_value(iter, MODEL_FIELD_NODE)
+        pixbuf = getPixbufForNode(node)
+        cell.set_property('pixbuf', pixbuf)"""                
+        favicon = os.path.join( Configuration.GLADEPATH, 'browser.png' )
+        fname = model.get_value(iter, COLUMN_SEVERITY )
+        site = self.items[ fname ]
+        if site.data['DocumentRoot'] != None:
+            custom_favicon = os.path.join(os.path.dirname( site.data['DocumentRoot']+"/" ), "favicon.ico")                                                    
+            if ( os.path.exists( custom_favicon ) ): favicon = custom_favicon
+            
+        pixbuf = gtk.gdk.pixbuf_new_from_file( favicon )
+        cell.set_property("pixbuf", pixbuf)
+gobject.type_register ( ModulesTreeView )

=== added file 'build/lib.linux-x86_64-2.6/RapacheGtk/VirtualHostGui.py'
--- build/lib.linux-x86_64-2.6/RapacheGtk/VirtualHostGui.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheGtk/VirtualHostGui.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,295 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+""".
+Issues with the new window:
+    - self.parent doesn't work
+    - onblur doesn't trigger when pressing Return
+    - changing a domain name doesn't change subdomains
+    - empty server aliases shuoldn't be managed
+ALSO:
+    - please implement a delete directive func in the parser
+    - move denorm. vhosts in another tab
+    - merge with Qense warning window
+"""
+
+import sys
+import re
+
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+
+import os
+import pango
+import tempfile
+import traceback
+import RapacheGtk.GuiUtils
+from RapacheCore.VirtualHost import *
+from RapacheGtk import GuiUtils
+from EditDomainNameGui import EditDomainNameWindow
+        
+class VirtualHostWindow:
+    
+    def __init__ ( self, parent = None):
+           
+        self.vhost = None
+        self.create_new = True
+        self.parent = parent
+        self.plugins = []
+
+        gladefile = os.path.join(Configuration.GLADEPATH, "edit_vhost.glade")
+        wtree = gtk.glade.XML(gladefile)
+        
+        self.window = wtree.get_widget("dialog_edit_vhost")
+        self.entry_domain = wtree.get_widget("entry_domain")
+        self.entry_location = wtree.get_widget("entry_location")
+        self.button_location = wtree.get_widget("button_location")
+        self.treeview_domain = wtree.get_widget("treeview_domain")
+        self.checkbutton_hosts = wtree.get_widget("checkbutton_hosts")
+        self.toolbutton_domain_add = wtree.get_widget("toolbutton_domain_add")
+        self.toolbutton_domain_edit = wtree.get_widget("toolbutton_domain_edit")
+        self.toolbutton_domain_delete = wtree.get_widget("toolbutton_domain_delete")
+        self.notebook = wtree.get_widget("notebook")
+        self.button_save = wtree.get_widget("button_save")
+        self.error_area = wtree.get_widget("error_area")
+        signals = {
+            "on_toolbutton_domain_add_clicked"       : self.on_toolbutton_domain_add_clicked,
+            "on_toolbutton_domain_edit_clicked"     : self.on_toolbutton_domain_edit_clicked,
+            "on_toolbutton_domain_delete_clicked"   : self.on_toolbutton_domain_delete_clicked,
+            "on_button_save_clicked"            : self.on_button_save_clicked,
+            "on_button_cancel_clicked"          : self.on_button_cancel_clicked,
+            "on_entry_domain_changed"              : self.on_entry_domain_changed,
+            "on_button_location_clicked"        : self.on_button_location_clicked,
+            "on_entry_domain_focus_out_event"    : self.on_entry_domain_focus_out_event,
+            "on_button_location_clear_clicked"    : self.on_button_location_clear_clicked
+        }
+        wtree.signal_autoconnect(signals)
+        
+        self.text_view_vhost_source = GuiUtils.new_apache_sourceview()
+        wtree.get_widget( 'text_view_vhost_source_area' ).add( self.text_view_vhost_source )
+        self.text_view_vhost_source.set_editable( False )
+        self.text_view_vhost_source.show()
+                
+        self.notebook.get_nth_page( 1 ).hide()
+        self.notebook.get_nth_page( 2 ).hide()
+        
+        # add on destroy to quit loop
+        self.window.connect("destroy", self.on_destroy)
+        
+        # Setup tree
+        column = gtk.TreeViewColumn(('Domains'))
+        column.set_spacing(4)
+        cell = gtk.CellRendererText()
+        column.pack_start(cell, True)
+        column.set_attributes(cell, markup=0)
+        self.treeview_domain.append_column(column)
+        
+        self.treeview_domain_store = gtk.ListStore(str, object)
+        self.treeview_domain.set_model(self.treeview_domain_store)
+
+        GuiUtils.style_as_tooltip( self.error_area )
+        self.on_entry_domain_changed()
+        
+    def run(self):
+
+        # Load UI Plugins
+        if self.vhost:
+            site = self.vhost
+        else:
+            # load default  
+            site = VirtualHostModel( "", self.parent.plugin_manager)
+            
+        for plugin in self.parent.plugin_manager.plugins:
+        	try:
+        	    if plugin.is_enabled():      	        
+        	        plugin.load_vhost_properties(self.notebook, site.data)
+    	        	self.plugins.append(plugin)
+        	except Exception:
+        		traceback.print_exc(file=sys.stdout)
+
+        self.window.show()           
+        gtk.main()
+
+    def load (self, name ):
+        self.vhost = VirtualHostModel( name )
+        self.create_new = False
+        try:
+            self.vhost.load(False, self.parent.plugin_manager)
+            print self.vhost.data
+            #self._get( 'has_www' ).set_active( site.data[ 'has_www' ] )
+            server_name = self.vhost.data[ 'ServerName' ] 
+            if ( server_name != None ):
+                self.entry_domain.set_text( server_name )
+            document_root = self.vhost.data[ 'DocumentRoot' ] 
+            if ( document_root != None ):
+                self.entry_location.set_text( document_root )
+            server_alias = self.vhost.data[ 'ServerAlias' ]
+            if ( server_alias != None ): 
+                for domain in server_alias:
+                    self.treeview_domain_store.append((domain, None))            
+            print self.vhost.data
+        except "VhostUnparsable":            
+            pass
+        
+        buf = self.text_view_vhost_source.get_buffer()
+        buf.set_text( self.vhost.get_source() )
+        
+
+
+    def get_domain (self):
+        return self.entry_domain.get_text().strip()
+        #url.lower().startswith('http://')
+        #url[7:]
+    def set_default_values_from_domain(self, force_domain=False):
+        domain = self.get_domain()
+        
+        # auto set the location
+        if domain and (not self.entry_location.get_text() or force_domain):
+            self.entry_location.set_text( "/srv/www/%s" % (domain +"/httpdocs" ))
+        if force_domain and not domain:
+            self.entry_location.set_text("")
+
+        # auto create a www entry
+        #if not force_domain and domain and len(self.treeview_domain_store) == 0 and not domain.startswith("www"):
+        #    self.treeview_domain_store.append(("www." + domain, None))
+
+    def on_entry_domain_focus_out_event(self, widget, opt):
+        self.set_default_values_from_domain()
+        
+    def on_entry_domain_changed(self, unused_widget = None):
+        widget = self.entry_domain
+        name = widget.get_text()
+        if ( valid_domain_name( name ) ):
+            self.button_save.set_sensitive(True);
+            #if self.create_new :
+            #    self.xml.get_widget( 'default_folder' ).set_text( '/srv/www/'+name+'/httpdocs' )
+        else:
+            self.button_save.set_sensitive(False); 
+    
+    def on_button_location_clear_clicked(self, widget):
+        self.set_default_values_from_domain(True)
+
+
+    def on_button_location_clicked(self, widget):
+        chooser = gtk.FileChooserDialog(
+            title=None,
+            action=gtk.FILE_CHOOSER_ACTION_CREATE_FOLDER,
+                        buttons=(gtk.STOCK_CANCEL,
+                        gtk.RESPONSE_CANCEL,
+                        gtk.STOCK_OPEN,
+                        gtk.RESPONSE_OK))
+                        
+        location = self.entry_location.get_text().strip()
+        if not location:
+            location = "/srv/www"    
+        chooser.set_current_folder(location)
+        response = chooser.run()
+        
+        if response == gtk.RESPONSE_OK:
+            self.entry_location.set_text( chooser.get_filename() )
+        chooser.destroy()
+
+    def on_destroy(self, widget, data=None):
+        gtk.main_quit()
+
+    def on_toolbutton_domain_add_clicked(self, widget):
+        edw = EditDomainNameWindow(self.entry_domain.get_text().strip())
+        domain = edw.run()
+        if domain:
+            self.treeview_domain_store.append((domain, None))
+        return
+    def  get_server_aliases_list (self ):
+        aliases = []
+        for row in self.treeview_domain_store: aliases.append( row[0] )
+        return aliases
+    def on_toolbutton_domain_edit_clicked(self, widget):
+    
+        model, iter = self.treeview_domain.get_selection().get_selected()
+        if not iter: return
+        domain = model.get_value(iter, 0)
+        print domain
+        edw = EditDomainNameWindow( domain )
+        result = edw.run()
+        if result:
+            self.treeview_domain_store.set_value(iter, 0, edw.return_value)
+        return     
+             
+    def on_toolbutton_domain_delete_clicked(self, widget):
+        model, iter = self.treeview_domain.get_selection().get_selected()
+        if not iter: return
+        self.treeview_domain_store.remove(iter)
+        return  
+            
+    def on_button_save_clicked(self, widget):
+        if self.entry_location.get_text() == "" and self.create_new:
+            self.set_default_values_from_domain( True )
+        
+        options = {}
+        options[ 'ServerAlias' ] =  []
+        options[ 'ServerName' ] = self.entry_domain.get_text()
+        options[ 'hack_hosts' ] = self.checkbutton_hosts.get_active()                
+        options[ 'DocumentRoot' ] = self.entry_location.get_text()
+        options[ 'ServerAlias' ] = self.get_server_aliases_list()
+
+	    # Save plugins
+        if self.plugins:
+            for plugin in self.plugins:
+                try:
+                    if plugin.is_enabled():
+                        plugin.save_vhost_properties(options)
+                except Exception:
+                    traceback.print_exc(file=sys.stdout) 
+
+        print options
+        
+        try:
+            if ( self.create_new ):
+                site = VirtualHostModel( options[ 'ServerName' ] )
+                site.create ( options )
+            else:
+                name = self.vhost.data['name']
+                print "Current name:", name
+                site = VirtualHostModel( name )
+                site.update( options, name )
+
+            
+            #self.parent.create_vhost_list()        
+            self.parent.refresh_vhosts()
+            self.parent.please_restart()
+            self.window.destroy()
+        except "VhostExists":
+           print "========================"
+           self.show_error( "A virtual host with the same name already exists" )     
+        
+                         
+    def on_button_cancel_clicked(self, widget):
+        self.window.destroy()
+        return    
+    def show_error ( self, message ):
+        
+        self.xml.get_widget( 'message_text' ).set_label( '<b>'+message+'</b>' )
+        self.xml.get_widget( 'message_container' ).show()                 
+

=== added file 'build/lib.linux-x86_64-2.6/RapacheGtk/WarningWindow.py'
--- build/lib.linux-x86_64-2.6/RapacheGtk/WarningWindow.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheGtk/WarningWindow.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+    
+import os
+import gnome.ui
+
+from RapacheGtk import GuiUtils
+from RapacheCore import Configuration
+
+class WarningWindow:
+	"""The Rapache warning window"""
+
+	def __init__(self, warning, father = None):
+		self.father = father
+		self.gladefile = Configuration.GLADEPATH + "/" + "warning_dialog.glade"
+		print self.gladefile
+		self.xml =  gtk.glade.XML(self.gladefile)
+		#Create our dictionary and connect it
+		dic = { 
+			"quit" : gtk.main_quit
+			, "on_ok" : gtk.main_quit
+			}
+		self.xml.signal_autoconnect(dic)
+		self.xml.get_widget( 'label1' ).set_label ( warning )  
+		                  
+

=== added file 'build/lib.linux-x86_64-2.6/RapacheGtk/__init__.py'
=== added file 'build/lib.linux-x86_64-2.6/RapacheGtk/old_VirtualHostGui.py'
--- build/lib.linux-x86_64-2.6/RapacheGtk/old_VirtualHostGui.py	1970-01-01 00:00:00 +0000
+++ build/lib.linux-x86_64-2.6/RapacheGtk/old_VirtualHostGui.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import re
+
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+
+import os
+import pango
+import tempfile
+
+from RapacheCore.VirtualHost import *
+from RapacheGtk import GuiUtils
+        
+class VirtualHostWindow:
+    
+    create_new = True
+    name = None
+    
+    def __init__ ( self, father = None):
+        self.father = father
+        self.gladefile = Configuration.GLADEPATH + "/" + "edit_vhost.glade"  
+        self.xml = gtk.glade.XML(self.gladefile)     
+        #Create our dictionary and connect it
+        dic = { 
+            "quit" : self.quit
+            , "on_ok":self.save
+            , "on_cancel":self.close  
+            , "domain_name_updated":self.domain_name_updated
+            , "custom_folder_toggled":self.custom_folder_toggled
+            }
+        self.xml.signal_autoconnect(dic)
+        self.xml.get_widget( 'custom_folder' ).set_action ( gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER )                
+        font_desc = pango.FontDescription('monospace')
+        self.xml.get_widget( 'vhost_source' ).modify_font(font_desc)
+        GuiUtils.style_as_tooltip( self.xml.get_widget( 'message_container' ) )
+   
+    def load (self, name ):
+
+        site = VirtualHostModel( name )
+        self.create_new = False
+        self.name = name 
+        self._get( 'create_hosts_entry' ).hide()
+        self._get( 'create_hosts_label' ).hide()
+        try:
+            site.load()
+            self._get( 'has_www' ).set_active( site.data[ 'has_www' ] )
+            self._get( 'domain_name' ).set_text( site.data[ 'ServerName' ] )
+            self._get( 'default_folder' ).set_text( site.data[ 'DocumentRoot' ] )
+            self.xml.get_widget( 'ok_button' ).set_sensitive(True);
+        except "VhostUnparsable":            
+            self._get( 'notebook' ).get_nth_page( 0 ).hide()
+        buffer = self.xml.get_widget( 'vhost_source' ).get_buffer()
+        buffer.set_text( site.get_source() )
+    def _get(self, id ):
+        return self.xml.get_widget( id )
+    
+    
+    def error ( self, message ):
+        self.xml.get_widget( 'message_text' ).set_label( '<b>'+message+'</b>' )
+        self.xml.get_widget( 'message_container' ).show()
+        
+    def quit (self, widget):      
+        self.father.new_vhost_window = None
+    
+    def close ( self, widget = None ):
+        self.window = self.xml.get_widget( 'vhost_edit_window' )
+        self.window.destroy()
+    def domain_name_updated ( self, widget, a = None, b = None, c = None ):
+        name = widget.get_text()
+        if ( valid_domain_name( name ) ):
+            self.xml.get_widget( 'ok_button' ).set_sensitive(True);
+            if self.create_new :
+                self.xml.get_widget( 'default_folder' ).set_text( '/var/www/'+name+'/httpdocs' )
+        else:
+            self.xml.get_widget( 'ok_button' ).set_sensitive(False);
+    def custom_folder_toggled( self, widget ):
+        if ( widget.get_active() == True ):
+            self.xml.get_widget( 'custom_folder' ).show()
+            self.xml.get_widget( 'default_folder' ).hide()
+        else:
+            self.xml.get_widget( 'custom_folder' ).hide()
+            self.xml.get_widget( 'default_folder' ).show()            
+    
+    
+    def save( self, widget ):
+        options = {}
+        options[ 'has_www' ] = self.xml.get_widget( 'has_www' ).get_active()     
+        options[ 'domain_name' ] = ( self.xml.get_widget( 'domain_name' ).get_text() )
+        options[ 'hack_hosts' ] = self.xml.get_widget( 'create_hosts_entry' ).get_active()                
+        if self.xml.get_widget( 'set_custom_folder' ).get_active():
+            DocumentRoot =  self.xml.get_widget( 'custom_folder' ).get_filename ()     
+        else:
+            DocumentRoot =  self.xml.get_widget( 'default_folder' ).get_text()
+        options[ 'DocumentRoot' ] = DocumentRoot
+                       
+        
+        try:
+            if ( self.create_new ):
+                site = VirtualHostModel( options[ 'domain_name' ] )
+                site.create ( options )
+            else:
+                print "Current name:", self.name
+                site = VirtualHostModel( self.name )
+                site.update( options, self.name )
+            
+            self.father.refresh_vhosts()        
+            self.father.please_restart()
+            self.close()
+        except "VhostExists":
+           print "========================"
+           self.error( "A virtual host with the same name already exists" )     
+        
+             
+        return True

=== added directory 'build/scripts-2.6'
=== added file 'build/scripts-2.6/hosts-manager'
--- build/scripts-2.6/hosts-manager	1970-01-01 00:00:00 +0000
+++ build/scripts-2.6/hosts-manager	2010-05-16 16:14:24 +0000
@@ -0,0 +1,22 @@
+#!/usr/bin/python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from RapacheCore.HostsManager import HostsManager
+
+if __name__ == "__main__":
+    HostsManager( True )
\ No newline at end of file

=== added file 'build/scripts-2.6/rapache'
--- build/scripts-2.6/rapache	1970-01-01 00:00:00 +0000
+++ build/scripts-2.6/rapache	2010-05-16 16:14:24 +0000
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import os.path
+
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+
+import os
+
+from RapacheGtk.RapacheGui import MainWindow
+from RapacheGtk.WarningWindow import WarningWindow
+from RapacheCore import Configuration
+
+
+if __name__ == "__main__":
+		current_path = os.path.abspath(os.path.dirname(__file__))
+		if ( os.path.exists( current_path+"/RapacheCore" ) ):
+		    #self-contained mode
+		    Configuration.APPPATH = os.path.abspath(os.path.dirname(__file__))
+		    Configuration.GLADEPATH = Configuration.APPPATH + "/Glade"    
+
+		if( os.path.isdir( Configuration.SITES_AVAILABLE_DIR ) and os.path.isdir( Configuration.SITES_ENABLED_DIR )):
+	   		hwg = MainWindow()
+			gtk.main()
+		else: 
+			ww = WarningWindow("Apache isn't installed. Rapache has nothing to manage.")   
+			gtk.main()    

=== added directory 'data'
=== renamed directory 'data' => 'data.moved'
=== added file 'data/rapache.desktop'
--- data/rapache.desktop	1970-01-01 00:00:00 +0000
+++ data/rapache.desktop	2010-05-16 16:14:24 +0000
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Name=rapache
+Comment=Simple tool for managing and configuring an apache2 instance
+TryExec=rapache
+Exec=rapache
+Icon=/usr/share/rapache/Glade/icon_cadsoft_eagle.svg
+Type=Application
+Categories=GNOME;GTK;Settings;DesktopSettings;
+

=== added file 'hosts-manager'
--- hosts-manager	1970-01-01 00:00:00 +0000
+++ hosts-manager	2010-05-16 16:14:24 +0000
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from RapacheCore.HostsManager import HostsManager
+
+if __name__ == "__main__":
+    HostsManager( True )
\ No newline at end of file

=== renamed file 'hosts-manager' => 'hosts-manager.moved'
=== added file 'rapache'
--- rapache	1970-01-01 00:00:00 +0000
+++ rapache	2010-05-16 16:14:24 +0000
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import os.path
+
+try:
+     import pygtk
+     pygtk.require("2.0")
+except:
+      pass
+try:
+    import gtk
+    import gtk.glade
+except:
+    sys.exit(1)
+
+import os
+
+from RapacheGtk.RapacheGui import MainWindow
+from RapacheGtk.WarningWindow import WarningWindow
+from RapacheCore import Configuration
+
+
+if __name__ == "__main__":
+		current_path = os.path.abspath(os.path.dirname(__file__))
+		if ( os.path.exists( current_path+"/RapacheCore" ) ):
+		    #self-contained mode
+		    Configuration.APPPATH = os.path.abspath(os.path.dirname(__file__))
+		    Configuration.GLADEPATH = Configuration.APPPATH + "/Glade"    
+
+		if( os.path.isdir( Configuration.SITES_AVAILABLE_DIR ) and os.path.isdir( Configuration.SITES_ENABLED_DIR )):
+	   		hwg = MainWindow()
+			gtk.main()
+		else: 
+			ww = WarningWindow("Apache isn't installed. Rapache has nothing to manage.")   
+			gtk.main()    

=== renamed file 'rapache' => 'rapache.moved'
=== added file 'setup.py'
--- setup.py	1970-01-01 00:00:00 +0000
+++ setup.py	2010-05-16 16:14:24 +0000
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza,  Jason Taylor, Emanuele Gentili
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import subprocess, glob, os.path
+from os import path
+from distutils.core import setup
+setup(
+    name='rapache',
+    author='Rapache Developers',
+    author_email='rapache-devel@xxxxxxxxxxxxxxxxxxx',
+    maintainer='Emanuele Gentili',
+    maintainer_email='emgent@xxxxxxxxxx',
+    description='Simple tool for managing and configuring an apache2 instance',
+    url = 'http://www.rapache.org',
+    license='GNU GPL',
+    packages=['RapacheCore', 'RapacheGtk'],
+    scripts=['rapache', 'hosts-manager'],
+    data_files=[
+                ('/usr/share/rapache/Glade', glob.glob('Glade/*')),
+                ('/usr/share/applications', ['data/rapache.desktop']),
+               ],
+    )
+

=== renamed file 'setup.py' => 'setup.py.moved'

Follow ups