48cacfdc2ca6

vim: add ropevim
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Wed, 06 Oct 2010 12:30:46 -0400
parents e30544496575
children 0d2e98797a8c
branches/tags (none)
files vim/.vimrc vim/sadness/ropevim/install_ropevim.sh vim/sadness/ropevim/pylibs/rope vim/sadness/ropevim/pylibs/ropemode vim/sadness/ropevim/pylibs/ropevim.py vim/sadness/ropevim/rope.vim vim/sadness/ropevim/src/rope/.hgignore vim/sadness/ropevim/src/rope/.hgtags vim/sadness/ropevim/src/rope/CONTRIBUTORS vim/sadness/ropevim/src/rope/COPYING vim/sadness/ropevim/src/rope/MANIFEST.in vim/sadness/ropevim/src/rope/README.txt vim/sadness/ropevim/src/rope/docs/contributing.txt vim/sadness/ropevim/src/rope/docs/dev/issues.txt vim/sadness/ropevim/src/rope/docs/dev/todo.txt vim/sadness/ropevim/src/rope/docs/done.txt vim/sadness/ropevim/src/rope/docs/library.txt vim/sadness/ropevim/src/rope/docs/overview.txt vim/sadness/ropevim/src/rope/docs/rope.txt vim/sadness/ropevim/src/rope/rope/__init__.py vim/sadness/ropevim/src/rope/rope/base/__init__.py vim/sadness/ropevim/src/rope/rope/base/arguments.py vim/sadness/ropevim/src/rope/rope/base/ast.py vim/sadness/ropevim/src/rope/rope/base/astutils.py vim/sadness/ropevim/src/rope/rope/base/builtins.py vim/sadness/ropevim/src/rope/rope/base/change.py vim/sadness/ropevim/src/rope/rope/base/codeanalyze.py vim/sadness/ropevim/src/rope/rope/base/default_config.py vim/sadness/ropevim/src/rope/rope/base/evaluate.py vim/sadness/ropevim/src/rope/rope/base/exceptions.py vim/sadness/ropevim/src/rope/rope/base/fscommands.py vim/sadness/ropevim/src/rope/rope/base/history.py vim/sadness/ropevim/src/rope/rope/base/libutils.py vim/sadness/ropevim/src/rope/rope/base/oi/__init__.py vim/sadness/ropevim/src/rope/rope/base/oi/doa.py vim/sadness/ropevim/src/rope/rope/base/oi/memorydb.py vim/sadness/ropevim/src/rope/rope/base/oi/objectdb.py vim/sadness/ropevim/src/rope/rope/base/oi/objectinfo.py vim/sadness/ropevim/src/rope/rope/base/oi/runmod.py vim/sadness/ropevim/src/rope/rope/base/oi/soa.py vim/sadness/ropevim/src/rope/rope/base/oi/soi.py vim/sadness/ropevim/src/rope/rope/base/oi/transform.py vim/sadness/ropevim/src/rope/rope/base/prefs.py vim/sadness/ropevim/src/rope/rope/base/project.py vim/sadness/ropevim/src/rope/rope/base/pycore.py vim/sadness/ropevim/src/rope/rope/base/pynames.py vim/sadness/ropevim/src/rope/rope/base/pynamesdef.py vim/sadness/ropevim/src/rope/rope/base/pyobjects.py vim/sadness/ropevim/src/rope/rope/base/pyobjectsdef.py vim/sadness/ropevim/src/rope/rope/base/pyscopes.py vim/sadness/ropevim/src/rope/rope/base/resourceobserver.py vim/sadness/ropevim/src/rope/rope/base/resources.py vim/sadness/ropevim/src/rope/rope/base/simplify.py vim/sadness/ropevim/src/rope/rope/base/stdmods.py vim/sadness/ropevim/src/rope/rope/base/taskhandle.py vim/sadness/ropevim/src/rope/rope/base/utils.py vim/sadness/ropevim/src/rope/rope/base/worder.py vim/sadness/ropevim/src/rope/rope/contrib/__init__.py vim/sadness/ropevim/src/rope/rope/contrib/autoimport.py vim/sadness/ropevim/src/rope/rope/contrib/changestack.py vim/sadness/ropevim/src/rope/rope/contrib/codeassist.py vim/sadness/ropevim/src/rope/rope/contrib/finderrors.py vim/sadness/ropevim/src/rope/rope/contrib/findit.py vim/sadness/ropevim/src/rope/rope/contrib/fixmodnames.py vim/sadness/ropevim/src/rope/rope/contrib/fixsyntax.py vim/sadness/ropevim/src/rope/rope/contrib/generate.py vim/sadness/ropevim/src/rope/rope/refactor/__init__.py vim/sadness/ropevim/src/rope/rope/refactor/change_signature.py vim/sadness/ropevim/src/rope/rope/refactor/encapsulate_field.py vim/sadness/ropevim/src/rope/rope/refactor/extract.py vim/sadness/ropevim/src/rope/rope/refactor/functionutils.py vim/sadness/ropevim/src/rope/rope/refactor/importutils/__init__.py vim/sadness/ropevim/src/rope/rope/refactor/importutils/actions.py vim/sadness/ropevim/src/rope/rope/refactor/importutils/importinfo.py vim/sadness/ropevim/src/rope/rope/refactor/importutils/module_imports.py vim/sadness/ropevim/src/rope/rope/refactor/inline.py vim/sadness/ropevim/src/rope/rope/refactor/introduce_factory.py vim/sadness/ropevim/src/rope/rope/refactor/introduce_parameter.py vim/sadness/ropevim/src/rope/rope/refactor/localtofield.py vim/sadness/ropevim/src/rope/rope/refactor/method_object.py vim/sadness/ropevim/src/rope/rope/refactor/move.py vim/sadness/ropevim/src/rope/rope/refactor/multiproject.py vim/sadness/ropevim/src/rope/rope/refactor/occurrences.py vim/sadness/ropevim/src/rope/rope/refactor/patchedast.py vim/sadness/ropevim/src/rope/rope/refactor/rename.py vim/sadness/ropevim/src/rope/rope/refactor/restructure.py vim/sadness/ropevim/src/rope/rope/refactor/similarfinder.py vim/sadness/ropevim/src/rope/rope/refactor/sourceutils.py vim/sadness/ropevim/src/rope/rope/refactor/suites.py vim/sadness/ropevim/src/rope/rope/refactor/topackage.py vim/sadness/ropevim/src/rope/rope/refactor/usefunction.py vim/sadness/ropevim/src/rope/rope/refactor/wildcards.py vim/sadness/ropevim/src/rope/ropetest/__init__.py vim/sadness/ropevim/src/rope/ropetest/advanced_oi_test.py vim/sadness/ropevim/src/rope/ropetest/builtinstest.py vim/sadness/ropevim/src/rope/ropetest/codeanalyzetest.py vim/sadness/ropevim/src/rope/ropetest/contrib/__init__.py vim/sadness/ropevim/src/rope/ropetest/contrib/autoimporttest.py vim/sadness/ropevim/src/rope/ropetest/contrib/changestacktest.py vim/sadness/ropevim/src/rope/ropetest/contrib/codeassisttest.py vim/sadness/ropevim/src/rope/ropetest/contrib/finderrorstest.py vim/sadness/ropevim/src/rope/ropetest/contrib/findittest.py vim/sadness/ropevim/src/rope/ropetest/contrib/fixmodnamestest.py vim/sadness/ropevim/src/rope/ropetest/contrib/generatetest.py vim/sadness/ropevim/src/rope/ropetest/historytest.py vim/sadness/ropevim/src/rope/ropetest/objectdbtest.py vim/sadness/ropevim/src/rope/ropetest/objectinfertest.py vim/sadness/ropevim/src/rope/ropetest/projecttest.py vim/sadness/ropevim/src/rope/ropetest/pycoretest.py vim/sadness/ropevim/src/rope/ropetest/pyscopestest.py vim/sadness/ropevim/src/rope/ropetest/refactor/__init__.py vim/sadness/ropevim/src/rope/ropetest/refactor/change_signature_test.py vim/sadness/ropevim/src/rope/ropetest/refactor/extracttest.py vim/sadness/ropevim/src/rope/ropetest/refactor/importutilstest.py vim/sadness/ropevim/src/rope/ropetest/refactor/inlinetest.py vim/sadness/ropevim/src/rope/ropetest/refactor/movetest.py vim/sadness/ropevim/src/rope/ropetest/refactor/multiprojecttest.py vim/sadness/ropevim/src/rope/ropetest/refactor/patchedasttest.py vim/sadness/ropevim/src/rope/ropetest/refactor/renametest.py vim/sadness/ropevim/src/rope/ropetest/refactor/restructuretest.py vim/sadness/ropevim/src/rope/ropetest/refactor/similarfindertest.py vim/sadness/ropevim/src/rope/ropetest/refactor/suitestest.py vim/sadness/ropevim/src/rope/ropetest/refactor/usefunctiontest.py vim/sadness/ropevim/src/rope/ropetest/runmodtest.py vim/sadness/ropevim/src/rope/ropetest/simplifytest.py vim/sadness/ropevim/src/rope/ropetest/testutils.py vim/sadness/ropevim/src/rope/setup.py vim/sadness/ropevim/src/ropemode/.hgignore vim/sadness/ropevim/src/ropemode/.hgtags vim/sadness/ropevim/src/ropemode/ropemode/__init__.py vim/sadness/ropevim/src/ropemode/ropemode/decorators.py vim/sadness/ropevim/src/ropemode/ropemode/dialog.py vim/sadness/ropevim/src/ropemode/ropemode/environment.py vim/sadness/ropevim/src/ropemode/ropemode/filter.py vim/sadness/ropevim/src/ropemode/ropemode/interface.py vim/sadness/ropevim/src/ropemode/ropemode/refactor.py vim/sadness/ropevim/src/ropemode/ropemodetest.py vim/sadness/ropevim/src/ropemode/setup.py vim/sadness/ropevim/src/ropevim/.hgtags vim/sadness/ropevim/src/ropevim/CONTRIBUTORS vim/sadness/ropevim/src/ropevim/COPYING vim/sadness/ropevim/src/ropevim/MANIFEST.in vim/sadness/ropevim/src/ropevim/README.txt vim/sadness/ropevim/src/ropevim/docs/done.txt vim/sadness/ropevim/src/ropevim/docs/ropevim.txt vim/sadness/ropevim/src/ropevim/docs/todo.txt vim/sadness/ropevim/src/ropevim/ropevim.py vim/sadness/ropevim/src/ropevim/ropevim.vim vim/sadness/ropevim/src/ropevim/setup.py

Changes

--- a/vim/.vimrc	Fri Oct 01 00:08:20 2010 -0400
+++ b/vim/.vimrc	Wed Oct 06 12:30:46 2010 -0400
@@ -252,6 +252,9 @@
 map <F4> :TlistToggle<cr>
 map <leader>T :!/usr/local/bin/ctags -R .<CR>
 
+" Rope
+source $HOME/.vim/sadness/ropevim/rope.vim
+
 if has('gui_running')
     set guifont=Menlo:h12
     colorscheme molokai
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/install_ropevim.sh	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,64 @@
+#!/bin/bash
+
+# Plant rope vim's plugin
+# This is a script to install or update 'ropevim'
+# Copyright Alexander Artemenko, 2008
+# Contact me at svetlyak.40wt at gmail com
+
+function create_dirs
+{
+    mkdir -p src
+    mkdir -p pylibs
+}
+
+function check_vim
+{
+    if vim --version | grep '\-python[^3]' > /dev/null
+    then
+        echo You vim does not support python plugins.
+        echo Please, install vim with python support.
+        echo On debian or ubuntu you can do this:
+        echo "    sudo apt-get install vim-python"
+        exit 1
+    fi
+}
+
+function get_or_update
+{
+    if [ -e $1 ]
+    then
+        cd $1
+        echo Pulling updates from $2
+        hg pull > /dev/null
+        cd ..
+    else
+        echo Cloning $2
+        hg clone $2 $1 > /dev/null
+    fi
+}
+
+function pull_sources
+{
+    cd src
+    get_or_update rope http://bitbucket.org/agr/rope
+    get_or_update ropevim http://bitbucket.org/agr/ropevim
+    get_or_update ropemode http://bitbucket.org/agr/ropemode
+
+    cd ../pylibs
+    ln -f -s ../src/rope/rope
+    ln -f -s ../src/ropemode/ropemode
+    ln -f -s ../src/ropevim/ropevim.py
+    cd ..
+}
+
+function gen_vim_config
+{
+    echo "let \$PYTHONPATH .= \":`pwd`/pylibs\"" > rope.vim
+    echo "source `pwd`/src/ropevim/ropevim.vim" >> rope.vim
+    echo "Now, just add \"source `pwd`/rope.vim\" to your .vimrc"
+}
+
+check_vim
+create_dirs
+pull_sources
+gen_vim_config
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/pylibs/rope	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,1 @@
+../src/rope/rope
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/pylibs/ropemode	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,1 @@
+../src/ropemode/ropemode
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/pylibs/ropevim.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,1 @@
+../src/ropevim/ropevim.py
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/rope.vim	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,2 @@
+let $PYTHONPATH = "/Users/sjl/lib/dotfiles/vim/sadness/ropevim/pylibs:".$PYTHONPATH
+source /Users/sjl/lib/dotfiles/vim/sadness/ropevim/src/ropevim/ropevim.vim
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/.hgignore	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,4 @@
+syntax: glob
+
+*.pyc
+rope.egg-info
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/.hgtags	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,19 @@
+2b74d75e4f0a15e9a728e9642fd1a5dc50343544 0.7
+21d026b272052bf6e5798294409a6fc58dfe95fe 0.7.1
+dea8b62c2141d7459e67086efacb20cf422b5977 0.7.2
+edabbceda687af4ad93687e8d08c1e2d45a6181d 0.7.3
+c229ca17b51c169c11207ded55c05bae96b12a3e 0.7.4
+d05b87226c5410cd5427deaaa38f3e6d93bce272 0.7.5
+72c14e80687543b55aa38fc00538888212f6f11a 0.7.6
+ffcd014a92164f5df2206949fecce09ccb9bde9e 0.7.7
+ef7c349beeed1d763e545bce89754cb0154b837c 0.7.8
+b5ee6eb7f245e9713a5a1e45892ce9e5021680f8 0.7.9
+19960b1c3511de606ede66125edb487d299b4eac 0.8
+4b4db07361c5f09f5f3efd419bdb9cdfdac17b97 0.8.1
+31646f5ab763f85df9b01ba025f1475ca4db324a 0.8.2
+b77bd0f68d3eca884ea5001ec4f95c247eab40d2 0.8.3
+02b9af86ce327745783a21c140a609bc860a31bb 0.8.4
+5938069e8ca2ea309c0b23784806b2dc1d9b90cf 0.9
+62727f11b9666ccef926b5e4e6b849fff36e30e0 0.9.1
+a4a74d4469eb3f7f027bdd0cae64cf8143f52d94 0.9.2
+f8e015405cf4dfd0e4c8486f5e88505060bc458c 0.9.3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/CONTRIBUTORS	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,14 @@
+===================
+ Rope Contributors
+===================
+
+See Mercurial logs and the mailing list for details.
+
+* Alexander Solovyov <piranha@piranha.org.ua>
+* Sebastjan Trepca <trepca@gmail.com>
+* MATSUI Tetsushi <mft@users.sf.net>
+* Kevin Turner <keturn@keturn.net>
+* Darren Syzling <dsyzling@gmail.com>
+* Orestis Markou <orestis@gmail.com>
+* Ronny Pfannschmidt <ronny.pfannschmidt@gmail.com>
+* Anton Gritsay <general@angri.ru>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/COPYING	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  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.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the 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 a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE 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.
+
+		     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
+convey 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 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.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision 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, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This 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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/MANIFEST.in	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,4 @@
+include README.txt COPYING setup.py MANIFEST.in
+recursive-include rope *.py
+recursive-include docs *.txt
+recursive-include ropetest *.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/README.txt	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,56 @@
+========================================
+ rope, a python refactoring library ...
+========================================
+
+
+Overview
+========
+
+`Rope`_ is a python refactoring library.
+
+.. _`rope`: http://rope.sf.net/
+
+
+New Features
+============
+
+* codeassist: better handling of unicode in docstrings
+* codeassist: handling builtin unknowns, such as sys.stdout
+* codeassist: proposals scopes and types revised
+* fscommands: handle hg crew ui changes
+* patchedast: handle ExtSlice node
+
+Getting Started
+===============
+
+* List of features: `docs/rope.txt`_
+* Overview of some of rope's features: `docs/overview.txt`_
+* Using as a library: `docs/library.txt`_
+* Contributing: `docs/contributing.txt`_
+
+To change your project preferences edit
+``$PROJECT_ROOT/.ropeproject/config.py`` where ``$PROJECT_ROOT`` is
+the root folder of your project (this file is created the first time
+you open a project).
+
+
+Bug Reports
+===========
+
+Send your bug reports and feature requests to `rope-dev (at)
+googlegroups.com`_.
+
+.. _`rope-dev (at) googlegroups.com`: http://groups.google.com/group/rope-dev
+
+
+License
+=======
+
+This program is under the terms of GPL (GNU General Public License).
+Have a look at ``COPYING`` file for more information.
+
+
+.. _`docs/rope.txt`: docs/rope.html
+.. _`docs/overview.txt`: docs/overview.html
+.. _`docs/contributing.txt`: docs/contributing.html
+.. _`docs/library.txt`: docs/library.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/docs/contributing.txt	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,101 @@
+======================
+ Contributing to Rope
+======================
+
+
+Get Involved!
+=============
+
+Rope's main goal is being a good refactoring tool for python.  It also
+provides some IDE helpers.  If you like to contribute, you're welcome!
+
+
+How to Help Rope?
+=================
+
+Rope mailing list is `rope-dev (at) googlegroups.com`_.  You can send
+a mail to ``rope-dev-subscribe (at) googlegroups [dot] com`` to
+subscribe.
+
+* Use rope
+* Send bug reports and request features
+* Submit patches for bugs or new features
+* Discuss your ideas
+
+.. _`rope-dev (at) googlegroups.com`: http://groups.google.com/group/rope-dev
+
+
+Wish List
+=========
+
+You are welcome to send your patches to `rope-dev (at)
+googlegroups.com`_ mailing list.  Here is only a list of suggestions.
+
+Issues
+------
+
+The `dev/issues.txt`_ file is actually the main rope todo file.  There
+is a section called "unresolved issues"; it contains almost every kind
+of task.  Most of them need some thought or discussion.  Pickup
+whichever you are most interested in.  If you have ideas or questions
+about them, don't hesitate to discuss it in the mailing list.
+
+.. _`dev/issues.txt`: dev/issues.html
+
+Getting Ready For Python 3.0
+----------------------------
+
+Checkout http://bitbucket.org/agr/rope_py3k Mercurial_ repository.
+Contributions are welcome.
+
+Write Plugins For Other IDEs
+----------------------------
+
+See ropemacs_, ropevim_, eric4_ and ropeide_.
+
+
+.. _ropemacs: http://rope.sf.net/ropemacs.html
+.. _ropevim: http://rope.sf.net/ropevim.html
+.. _ropeide: http://rope.sf.net/ropeide.html
+.. _eric4: http://www.die-offenbachs.de/eric/index.html
+
+
+Rope Structure
+==============
+
+Rope package structure:
+
+* `rope.base`: the base part of rope
+* `rope.refactor`: refactorings and tools used in them
+* `rope.contrib`: IDE helpers
+
+Have a look at ``__init__.py`` of these packages or `library.txt`_ for
+more information.
+
+.. _`library.txt`: library.html
+
+
+Source Repository
+=================
+
+Rope uses Mercurial_ CMS:
+
+* Rope main branch: http://bitbucket.org/agr/rope
+* Rope py3k branch: http://bitbucket.org/agr/rope_py3k
+
+.. _Mercurial: http://selenic.com/mercurial
+
+
+Submitting patches
+==================
+
+Patches are welcome.
+
+Patch style
+-----------
+
+* Follow :PEP:`8`.
+* Use four spaces for indentation.
+* Include good unit-tests if possible.
+* Rope test suite should pass after patching
+* Use ``hg export`` format to preserve your identity
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/docs/dev/issues.txt	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,156 @@
+=============
+ Rope Issues
+=============
+
+
+Unresolved Issues
+=================
+
+* purging out less accurate callinfos when better ones appear?
+* using properties without calling its get?
+* global variable inlines
+* transform and extension modules
+* merging extract and usefunction
+* caching instances of PyObject
+* moving a group of elements together
+* temps might be read after body in usefunction or extract
+* usefunction and function returns
+* usefunction on methods
+* extracted functions should be inserted before using class bodies
+* adding "referenced later" wildcard argument to restructurings?
+* adding "change references" wildcard argument to restructurings?
+* ideas for more custom wildcards
+* adapting future python 2.6 ast changes
+* custom wildcards and recursive patterns
+* custom restructuring wildcard patterns and replacements
+* not reimporting back imports after moving
+* importing compressed objectdb/history data?
+* not applying all commenting mechanisms always in codeassist
+* fixing try blocks before current line in code_assist
+* better tests for patchedast
+* import actions with more that one phase and filtering problems
+* handle long imports should work on filtered imports unconditionally?
+* extracting subexpressions; look at `extracttest` for more info
+* switching to gplv3?
+* unignored files that are not under version control
+* inline fails when there is an arg mismatch
+* evaluate function parameter defaults in staticoi?
+* saving diffs instead of old contents in ChangeContents?
+* handling tuple parameters
+* extract class
+* analyzing function decorators
+* generate ... and implicit interfaces
+* generate method and class hierarchies
+* lambdas as functions; consider their parameters
+* renaming similarly named variables
+* handling the return type of ``yield`` keyword
+* not writing unchanged objectdb and history?
+
+
+To Be Reviewed
+==============
+
+* review patchedast; make it faster
+* lots of estimations in codeanalyze in WordRangeFinder
+* review objectdb modules
+* how concluded data are held for star imports
+
+
+Insert Before In Restructurings
+===============================
+
+Consider a restructuring like this::
+
+  pattern: ${a} if ${b} else ${c}
+  goal: replacement
+  before: if ${b}:\n    replacement = ${a}\nelse:\n    replacement = ${c}
+
+
+Memory Management
+=================
+
+These are the places in which rope spends most of the memory it
+consumes:
+
+* PyCore: for storing PyModules
+* ObjectInfo: for storing object information
+* History: for storing changes
+
+We should measure the amount of memory each of them use to make
+decisions.
+
+
+Custom Restructuring Wildcards
+==============================
+
+There is a need to add more custom wildcards in restructuring
+patterns.  But adding all such needs to `similarfinder` module makes
+it really complex.  So I think adding the ability to extend them is
+useful.
+
+Sometimes wildcards can be customized.  For instance one might want to
+match the function calls only if ``p1`` is passed in the arguments.
+They can be specified in wildcard arguments.
+
+Since matched wildcards can appear in the goal pattern, each wildcard
+should have a corresponding replacement wildcard.  Each replacement
+might be customized in each place it appears; for instance
+``${mycall:-p1}`` might mean to remove ``p1`` argument.
+
+
+Wildcard Format
+---------------
+
+All wildcards should appear as ``${name}``.  The type of wildcards and
+their parameters can be specified using the ``args`` argument of
+``Restructuring()``.
+
+Ideas:
+
+* Maybe we can put checks inside args, too::
+
+    pattern: ${project:type=rope.base.project.Project}.pycore
+
+  But what should be done when a variable appears twice::
+
+    pattern: ${a:type=__builtin__.int} + ${a}
+
+
+Examples
+--------
+
+.. ...
+
+
+Possible Module Renamings
+=========================
+
+*First level*:
+
+These module names are somehow inconsistent.
+
+* change -> changes
+* method_object -> methodobject
+* default_config -> defaultconfig
+
+*Second level*
+
+Many modules use long names.  They can be shortened without loss of
+readability.
+
+* methodobject -> methobj or funcobj
+* usefunction -> usefunc
+* multiproject -> mulprj
+* functionutils -> funcutils
+* importutils -> imputils
+* introduce_factory -> factory
+* change_signature -> signature
+* encapsulate_field -> encapsulate
+* sourceutils -> srcutils
+* resourceobserver -> observer
+
+
+Getting Ready For Python 3.0
+============================
+
+This has been moved to a separate branch.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/docs/dev/todo.txt	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,8 @@
+======
+ TODO
+======
+
+See the `unresolved issues` section of ``issues.txt`` file for more.
+
+
+> Public Release 1.0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/docs/done.txt	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,1105 @@
+===========
+ Done List
+===========
+
+
+> Public Release 0.9.3 : February 4, 2010
+
+
+- codeassist: proposals scopes and types revised : January 26, 2010
+
+
+- codeassist: handling "builtin unknowns" : January 06, 2010
+
+
+- refactor: fixed arguments in extracted method : December 26, 2009
+
+
+- pycore: fixed project's property `source_folders` : October 26, 2009
+
+
+- codeassist: better handling of unicode docstrings : August 20, 2009
+
+
+- setup.py: don't include docs as package data : July 18, 2009
+
+
+- fscommands: handle hg crew ui changes : May 04, 2009
+
+
+- patchedast: handle ExtSlice node : April 29, 2009
+
+
+> Public Release 0.9.2 : February 19, 2009
+
+
+- caching all sub-modules in `autoimport` : February 18 : 2009
+
+
+- extract method handles conditional variable updates : February 10, 2009
+
+
+- added basic support for setuptools : January 15, 2009
+
+
+- added `CompletionProposal.parameters` : November 4, 2008
+
+
+- fix recursion when creating modules : October 31, 2008
+
+
+> Public Release 0.9.1 : October 29, 2008
+
+
+- added import_dynload_stdmods project variable : October 28, 2008
+
+
+- finding dynload standard modules on windows : October 15, 2008
+
+
+> Public Release 0.9 : October 3, 2008
+
+
+- supporting Darcs VCS : August 20, 2008
+
+
+- handling files with mac line-ending : July 25, 2008
+
+
+- not searching all files when inlining a local variable : July 24, 2008
+
+
+> Public Release 0.8.4 : June 24, 2008
+
+
+- handling only_current for inline in other modules : July 21, 2008
+
+
+- inlining variable in other modules : July 19, 2008
+
+
+- added `rope.contrib.finderrors` : July 17, 2008
+
+
+- added `rope.contrib.fixmodnames` : July 16, 2008
+
+
+- added `rope.contrib.changestack` : July 15, 2008
+
+
+- better extension module handling : June 29, 2008
+
+
+- added `findit.Location.region` field : June 26, 2008
+
+
+- added `rope.contrib.findit.find_definition()` : June 26, 2008
+
+
+- added ``remove_self`` argument to `get_calltip()` : June 20, 2008
+
+
+> Public Release 0.8.3 : June 20, 2008
+
+
+- handling builtin modules in autoimport : June 12, 2008
+
+
+- creating parent folders of ``.ropeproject`` if don't exist : June 6, 2008
+
+
+- fixed inlining functions with line-breaks in arguments : May 22, 2008
+
+
+- added lineno to `rope.contrib.findit.Location` : May 19, 2008
+
+
+- deprecated some of `ChangeSignature` methods : May 19, 2008
+
+
+- added `ChangeSignature.get_args()` : May 19, 2008
+
+
+> Public Release 0.8.2 : May 10, 2008
+
+
+- inlining parameters : May 10, 2008
+
+
+- automatic default insertion in change signature : May 10, 2008
+
+
+- adding underlined parameter to `AutoImport` : May 7, 2008
+
+
+- added `rope.contrib.findit.find_implementations()` : April 28, 2008
+
+
+- moved `find_occurrences()` to `rope.contrib.findit` : April 25, 2008
+
+
+> Public Release 0.8.1 : April 20, 2008
+
+
+- added GIT support in fscommands : April 19, 2008
+
+
+- back importing underlined names in move : April 19, 2008
+
+
+- added `codeassist.get_calltip()` : April 12, 2008
+
+
+- added `libutils.analyze_modules()` : April 12, 2008
+
+
+- added ``soa_followed_calls`` project config : April 11, 2008
+
+
+- `libutils.report_change()` reads `automatic_soa` : April 10, 2008
+
+
+- SOA can follow functions : April 10, 2008
+
+
+- better handling of for, with and except variables : April 7, 2008
+
+
+- not reparsing unchanged modules for code assists : April 6, 2008
+
+
+- handling property as decorator : April 5, 2008
+
+
+> Public Release 0.8 : April 5, 2008
+
+
+- ignore_bad_imports project config : March 28, 2008
+
+
+- added AutoImport.get_name_locations() : March 17, 2008
+
+
+> Public Release 0.7.9 : March 14, 2008
+
+
+- Deprecated codeassist templates : March 14, 2008
+
+
+- Added in_hierarchy option to find occurrences : March 10, 2008
+
+
+- Faster class hierarchy analysis for refactorings : March 10, 2008
+
+
+- Added maxfixes to get doc and get definition location : March 6, 2008
+
+
+- Added extension_modules project config : March 6, 2008
+
+
+- Supporting builtin and c-extension modules : March 6, 2008
+
+
+> Public Release 0.7.8 : March 1, 2008
+
+
+- Extracting functions with only one return statement : February 29, 2008
+
+
+- Reporting errors for exceptional conditions in usefunction : February 29, 2008
+
+
+- More intelligent import handling for factory and move : February 25, 2008
+
+
+- Handling future imports in organize imports : February 20, 2008
+
+
+- Codeanalyze ignores comments when finding primaries : February 17, 2008
+
+
+- Organize import and dynload builtin modules on unix : February 16, 2008
+
+
+- Moved ImportOrganizer to rope.refactor.importutils : February 14, 2008
+
+
+- Moved ModuleToPackage to rope.refactor.topackage : February 14, 2008
+
+
+> Public Release 0.7.7 : February 13, 2008
+
+
+- Added python_files project config : February 10, 2008
+
+
+- Added codeassist.starting_expression() : February 10, 2008
+
+
+- Added AutoImport.clear_cache() : February 7, 2008
+
+
+- Improved extract function : February 1, 2008
+
+
+- Handling except variables : January 29, 2008
+
+
+> Public Release 0.7.6 : January 28, 2008
+
+
+- Handling unsure matches in restructurings : January 27, 2008
+
+
+- Added rope.contrib.autoimport : January 26, 2008
+
+
+- Added use function refactoring : January 25, 2008
+
+
+- Completing names after from-imports : January 23, 2008
+
+
+- Adding resources parameter to some refactorings : January 22, 2008
+
+
+- Deprecated in_file argument of `Rename.get_changes()` : January 22, 2008
+
+
+> Public Release 0.7.5 : January 17, 2008
+
+
+- Checking isinstance in restructurings : January 11, 2008
+
+
+- Better handling of one-liners : January 10, 2008
+
+
+- Choosing which files to apply a restructuring on : January 9, 2008
+
+
+- Allowing customizable restructuring wildcards : January 7, 2008
+
+
+> Public Release 0.7.4 : January 3, 2008
+
+
+- Deprecated objectdb_type project config : December 23, 2007
+
+
+- Added save_objectdb config : December 23, 2007
+
+
+- Added compress_history and compress_objectdb configs : December 22, 2007
+
+
+> Public Release 0.7.3 : December 19, 2007
+
+
+- Inlining a single occurrence : December 13, 2007
+
+
+- Global extract method/variable : December 13, 2007
+
+
+> Public Release 0.7.2 : December 13, 2007
+
+
+- Specifying the number of fixes in code_assist : December 10, 2007
+
+
+- Deprecated `Pycore.create_(module|package)` : November 29, 2007
+
+
+- Performing refactorings across multiple projects : November 29, 2007
+
+
+> Public Release 0.7.1 : November 28, 2007
+
+
+- Better handling of symlinks in project path : November 27, 2007
+
+
+- Asking the user about unsure occurrences : November 10, 2007
+
+
+> Public Release 0.7 : November 1, 2007
+
+
+- ropemacs: moving elements, methods and modules : October 30, 2007
+
+
+- ropemacs: undoing refactorings : October 29, 2007
+
+
+- ropemacs: inline refactoring : October 29, 2007
+
+
+- ropemacs: extract method and local variable : October 29, 2007
+
+
+- ropemacs: goto definition : October 29, 2007
+
+
+- ropemacs: rename refactoring : October 29, 2007
+
+
+- A new open project dialog : October 10, 2007
+
+
+- Added `Core.add_extension()` : September 19, 2007
+
+
+> Public Release 0.6.2 : September 9, 2007
+
+
+- Setting statusbar, menu and bufferlist fonts in ``~/.rope`` : September 8, 2007
+
+
+- Better kill line : September 8, 2007
+
+
+- Using ``/``\s to match parent folders in find file : September 5, 2007
+
+
+- Fixed matching method implicit argument when extracting : September 5, 2007
+
+
+- An option for not removing the definition after inlining : September 1, 2007
+
+
+- Performing import actions on individual imports : September 1, 2007
+
+
+- ``C-u`` action prefix : September 1, 2007
+
+
+- Changing inline and move to use froms for back imports : August 27, 2007
+
+
+> Public Release 0.6.1 : August 19, 2007
+
+
+- Cleaning up `rope.ide.codeassist` : August 19, 2007
+
+
+- Showing unsure occurrences in show occurrences : August 17, 2007
+
+
+- Sorting scopes : August 9, 2007
+
+
+> Public Release 0.6 : August 5, 2007
+
+
+- Finding the scope in an overwritten scope : August 4, 2007
+
+
+- Added ``ignore_syntax_errors`` project config : August 2, 2007
+
+
+> Public Release 0.6m6 : July 29, 2007
+
+
+- Better diff highlighting : July 20, 2007
+
+
+- Handling imports when inlining : July 20, 2007
+
+
+- Handling recursive restructurings : July 18, 2007
+
+
+> Public Release 0.6m5 : July 15, 2007
+
+
+- Next/prev scope; ``M-C-e/M-C-a`` : July 9, 2007
+
+
+- Next/prev statement; ``M-e/M-a`` : July 8, 2007
+
+
+- Importing modules in restructurings : July 7, 2007
+
+
+- Auto-indentation in restructurings : July 6, 2007
+
+
+> Public Release 0.6m4 : July 1, 2007
+
+
+- Adding tools for making using rope library easier : June 23, 2007
+
+
+- Separating rope library from rope IDE : June 20, 2007
+
+
+- Restructuring checks for builtin objects using `__builtin__` : June 20, 2007
+
+
+> Public Release 0.6m3 : June 17, 2007
+
+
+- Self assignment warning : June 17, 2007
+
+
+- Adding support for Mercurial VCS : June 17, 2007
+
+
+- Inferring the object, list comprehensions hold : June 6, 2007
+
+
+> Public Release 0.6m2 : June 3, 2007
+
+
+- Enhancing extract method on staticmethods/classmethods : June 2, 2007
+
+
+- Extracting similar expressions/statements : May 30, 2007
+
+
+- Adding checks in restructuring dialog : May 23, 2007
+
+
+- Using `_ast` instead of `compiler` : May 23, 2007
+
+
+> Public Release 0.6m1 : May 20, 2007
+
+
+- Adding custom source folders in ``config.py`` : May 15, 2007
+
+
+- A simple UI for performing restructurings : May 15, 2007
+
+
+- Restructurings : May 14, 2007
+
+
+- Finding similar code : May 13, 2007
+
+
+- Patching ASTs to include formatting information : May 9, 2007
+
+
+> Public Release 0.5 : May 6, 2007
+
+
+- Better dialogs : May 2, 2007
+
+
+> Public Release 0.5rc1 : April 29, 2007
+
+
+- Showing current file history; ``C-x p 1 h`` : April 28, 2007
+
+
+- Open Type; ``C-x C-t`` : April 23, 2007
+
+
+- Adding persisted_memory objectdb : April 20, 2007
+
+
+- Adding sqlite objectdb : April 20, 2007
+
+
+> Public Release 0.5m5 : April 15, 2007
+
+
+- Encapsulating field in the defining class : April 13, 2007
+
+
+- Renaming occurrences in strings and comments : April 13, 2007
+
+
+- Stoppable refactorings : April 11, 2007
+
+
+- Faster automatic SOI analysis : April 9, 2007
+
+
+- Basic implicit interfaces : April 9, 2007
+
+
+- Automatic SOI analysis : April 6, 2007
+
+
+- Using a better object textual form : April 4, 2007
+
+
+- Spell-Checker : April 3, 2007
+
+
+> Public Release 0.5m4 : April 1, 2007
+
+
+- Incremental ObjectDB validation : March 31, 2007
+
+
+- Saving history across sessions : March 29, 2007
+
+
+- Saving object data to disk : March 28, 2007
+
+
+- Adding `.ropeproject` folder : Mark 26, 2007
+
+
+- Inlining `staticmethod`\s : March 23, 2007
+
+
+- Saving locations and texts : March 23, 2007
+
+
+- Generating python elements : March 21, 2007
+
+
+> Public Release 0.5m3 : March 18, 2007
+
+
+- Holding per name information for builtin containers : March 17, 2007
+
+
+- Filling paragraphs in text modes; ``M-q`` : March 15, 2007
+
+
+- Yanking; ``M-y`` : March 13, 2007
+
+
+- Repeating last command; ``C-x z`` : March 13, 2007
+
+
+- Adding 'rename when unsure' option : March 13, 2007
+
+
+- Change signature for constructors : March 11, 2007
+
+
+- Supporting generator functions : March 9, 2007
+
+
+- Enhancing show pydoc to include docs from superclasses : March 8, 2007
+
+
+- Enhanced returned object static object inference : March 8, 2007
+
+
+- Enhanced static object inference : March 8, 2007
+
+
+- Handling ``*args`` and ``**kwds`` arguments : March 7, 2007
+
+
+- Showing pydoc for some of builtin types and functions : March 7, 2007
+
+
+> Public Release 0.5m2 : March 4, 2007
+
+
+- Showing codetag/error/warning list : March 3, 2007
+
+
+- Registering templates in ``~/.rope`` : February 26, 2007
+
+
+- Auto-completing function keyword arguments when calling : February 26, 2007
+
+
+- Better status bar : February 23, 2007
+
+
+- Change occurrences : February 23, 2007
+
+
+- Moving methods : February 21, 2007
+
+
+> Public Release 0.5m1 : February 18, 2007
+
+
+- Handling ``with`` statements : February 15, 2007
+
+
+- Performing change signature in class hierarchies : February 14, 2007
+
+
+- Supporting builtin `zip` and `enumerate` : February 14, 2007
+
+
+- Replace method with method object : February 12, 2007
+
+
+- Enhancing searching : February 10, 2007
+
+
+- Execute command; ``M-x`` : February 10, 2007
+
+
+- Changing editor font and keybinding in ``~/.rope`` : February 9, 2007
+
+
+- Having two keybindings emacs/normal : February 9, 2007
+
+
+- Handling multi-key keyboard shortcuts : February 8, 2007
+
+
+- Fixing removing imports that eat the blank lines : February 8, 2007
+
+
+- Removing extra spaces and lines; ``C-c C-f`` : February 7, 2007
+
+
+> Public Release 0.4 : February 4, 2007
+
+
+- Reporting some of the refactoring problems in the UI : February 1, 2007
+
+
+> Public Release 0.4rc1 : January 28, 2007
+
+
+- Project History; Undoing refactorings in any order : January 25, 2007
+
+
+- Handling ``global`` keywords : January 22, 2007
+
+
+- Undoing everything; Project history : January 21, 2007
+
+
+- Removing `PythonRefactoring` facade : January 19, 2007
+
+
+- Basic lambdas handling : January 16, 2007
+
+
+- Handling builtin `property` : January 14, 2007
+
+
+> Public Release 0.4m5 : January 14, 2007
+
+
+- Handling long imports : January 11, 2007
+
+
+- Builtin functions : super, sorted, reversed, range : January 7, 2007
+
+
+- Support for file/open builtin type : January 7, 2007
+
+
+- Sorting imports; standard, third party, project : January 7, 2007
+
+
+- Enhanced dynamic object inference : January 5, 2007
+
+
+> Public Release 0.4m4 : December 31, 2006
+
+
+- Basic support for builtin types : December 29, 2006
+
+
+- Find occurrences; ``C-G`` : December 26, 2006
+
+
+- Ignoring ``*.pyc``, ``*~`` and ``.svn`` : December 26, 2006
+
+
+- Moving/renaming current module/package : December 25, 2006
+
+
+- Removing imports from the same module : December 22, 2006
+
+
+- Goto last edit location; ``C-q`` : December 20, 2006
+
+
+- Trying ``utf-8`` if defaults don't work : December 19, 2006
+
+
+- Comment line and region; ``C-c c``, ``C-c C-c`` : December 18, 2006
+
+
+> Public Release 0.4m3 : December 17, 2006
+
+
+- Introduce parameter : December 14, 2006
+
+
+- 8 spaces per tabs in `rope.base` and `rope.refactor` : December 8, 2006
+
+
+- Better support for other version control systems : December 8, 2006
+
+
+- Updating files that have been changed : December 8, 2006
+
+
+- Fixing module running on Windows : December 6, 2006
+
+
+> Public Release 0.4m2 : December 3, 2006
+
+
+- Change method signature : December 1, 2006
+
+
+- Change method signature dialog : November 30, 2006
+
+
+- Reordering parameters : November 28, 2006
+
+
+- Removing parameters : November 26, 2006
+
+
+- Inline parameter default value : November 26, 2006
+
+
+- Adding parameters : November 26, 2006
+
+
+- Normalizing function calls : November 26, 2006
+
+
+> Public Release 0.4m1 : November 19, 2006
+
+
+- Better help menu : November 15, 2006
+
+
+- Inline method refactoring : November 10, 2006
+
+
+> Public Release 0.3 : November 5, 2006
+
+
+- Better code assist proposal sorting and dialog : November 3, 2006
+
+
+- Extract method works with normal selection : October 31, 2006
+
+
+- Basic python file encoding support : October 31, 2006
+
+
+> Public Release 0.3rc1 : October 29, 2006
+
+
+- Unit-test running view : October 28, 2006
+
+
+- Previewing refactoring changes : October 25, 2006
+
+
+- Encapsulate field : October 19, 2006
+
+
+- Convert local variable to field refactoring : October 18, 2006
+
+
+> Public Release 0.3m5 : October 15, 2006
+
+
+- Code completions inside uncompleted ``try`` blocks : October 7, 2006
+
+
+- Single line extract method and variable : October 7, 2006
+
+
+- Hiding unappropriate menu items in different contexts : October 6, 2006
+
+
+- Inline local variable : October 5, 2006
+
+
+- Rename function parameters : October 5, 2006
+
+
+- Move a module or package to another package : October 4, 2006
+
+
+> Public Release 0.3m4 : October 1, 2006
+
+
+- Showing function signature in show doc : September 29, 2006
+
+
+- Goto line : September 29, 2006
+
+
+- Move refactoring for global class/function : September 29, 2006
+
+
+- Change relative imports to absolute : September 28, 2006
+
+
+- Changing from imports to normal imports : September 28, 2006
+
+
+- Removing duplicate imports : September 27, 2006
+
+
+- Expanding from-star-imports : September 27, 2006
+
+
+- Removing unused imports : September 27, 2006
+
+
+- Introduce factory method refactoring : September 25, 2006
+
+
+- Basic import tools : September 21, 2006
+
+
+- Separating concluded and structural data in `PyModule`\s : September 19, 2006
+
+
+> Public Release 0.3m3 : September 17, 2006
+
+
+- Basic subversion support using pysvn : September 14, 2006
+
+
+- Renaming methods in class hierarchy : September 12, 2006
+
+
+- Transform module to package refactoring : September 11, 2006
+
+
+> Public Release 0.3m2 : September 3, 2006
+
+
+- Better New ... Dialogs : September 2, 2006
+
+
+- Function argument dynamic object inference : September 2, 2006
+
+
+- Basic dynamic type inference : September 2, 2006
+
+
+- Better menus : August 27, 2006
+
+
+- Relative imports : August 23, 2006
+
+
+- Read ``__init__.py`` of packages : August 23, 2006
+
+
+- Extract function : August 22, 2006
+
+
+> Public Release 0.3m1 : August 20, 2006
+
+
+- Undoing refactorings : August 19, 2006
+
+
+- Making module dependancy graph : August 19, 2006
+
+
+- Rename modules/packages : August 18, 2006
+
+
+- Reloading changed editors after refactorings : August 17, 2006
+
+
+- Rename class/function : August 17, 2006
+
+
+- Function return object static type inference : August 15, 2006
+
+
+- Show PyDoc : August 15, 2006
+
+
+- Object inference for chained assignments : August 14, 2006
+
+
+> Public Release 0.2 : August 6, 2006
+
+
+- Resource tree view : August 5, 2006
+
+
+- Handle ``HTTPClient`` style names in go to next/prev word : August 2, 2006
+
+
+> Public Release 0.2RC : July 30, 2006
+
+
+- Asking whether to save modified buffers when exiting : July 29, 2006
+
+
+- Extending menus : July 25, 2006
+
+
+- ReST highlighting : July 24, 2006
+
+
+- Showing editor modified status : July 23, 2006
+
+
+- Sorting code assist proposals : July 22, 2006
+
+
+- Not renaming names in strings and comments in refactorings : July 22, 2006
+
+
+- Separating entering and correcting indentation : July 22, 2006
+
+
+> Public Release 0.2pre5 : July 16, 2006
+
+
+- Out of project modules : July 15, 2006
+
+
+- Handle circular from-imports : July 14, 2006
+
+
+- Completeing ``AClass(param).a_`` : July 11, 2006
+
+
+- We know the type of ``var = AClass()`` : July 4, 2006
+
+
+- Rename function parameter in the function : July 3, 2006
+
+
+> Public Release 0.2pre4 : July 2, 2006
+
+
+- Rename local variable : July 2, 2006
+
+
+- Complete as you type : July 2, 2006
+
+
+- Show quick outline; C-o : June 23, 2006
+
+
+- Go to definition; F3 : June 22, 2006
+
+
+> Public release 0.2pre3 : June 18, 2006
+
+
+- Auto-completing "self."s : June 13, 2006
+
+
+- Proposing base class attributes : June 12, 2006
+
+
+- Auto completion after "."s : June 8, 2006
+
+
+> Public Release 0.2pre2 : June 4, 2006
+
+
+- Next/prev word stops at underlines and capitals : May 29, 2006
+
+
+- Ignoring string and comment contents while indenting : May 29, 2006
+
+
+- Proposing templates in code-assist proposals : May 26, 2006
+
+
+- Auto-complete from-import imported objects : May 25, 2006
+
+
+- Not proposing variables which are not defined yet : May 23, 2006
+
+
+- Auto-completion should ignore current statement : May 23, 2006
+
+
+- Proposing function parameters in functions : May 22, 2006
+
+
+- Auto-complete local variable names : May 22, 2006
+
+
+> Public Release 0.2pre1 : May 20, 2006
+
+
+- Auto completing keywords and builtins : May 19, 2006
+
+
+- Auto-complete imported objects : May 19, 2006
+
+
+- Show searching status in the status bar : May 18, 2006
+
+
+- Auto-complete class and function names : May 16, 2006
+
+
+- Auto-complete global variables : May 14, 2006
+
+
+> Public Release 0.1 : May 8, 2006
+
+
+- Separating indenting and correcting indentation : May 7, 2006
+
+
+- Enhancing editor and indentation : May 4, 2006
+
+  - Pressing backspace should deindent
+  - Clearing undo list when opening a file; undoSeparator when saving
+
+
+- Showing current line in status bar : April 28, 2006
+
+
+- Switch editor dialog; C-x b and C-F6 : April 27, 2006
+
+
+- Make new package dialog : April 25, 2006
+
+
+- Make new module dialog : April 25, 2006
+
+
+> Public Release 0.1pre : April 22, 2006
+
+
+- Extending syntax highlighted elements : April 22, 2006
+
+
+- Auto indentation; C-i : April 20, 2006
+
+
+- Basic searching; C-s : April 12, 2006
+
+
+> SF registration : April 10, 2006
+
+
+- Multiple buffers : April 8, 2006
+  The editor should have a notebook view.
+
+
+- Enhancing dialogs : April 7, 2006
+  Using tkMessageBox, tkFileDialog, tkSimpleDialog, ScrolledText
+
+
+- Running modules : April 6, 2006
+  You should add the required directories to the python path.
+
+
+- Guessing source folders in the project : April 5, 2006
+
+
+- Finding a file in a project : April 4, 2006
+
+
+- Highlighting keywords : March 21, 2006
+  Only python files(``*.py``) should be highlighted.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/docs/library.txt	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,732 @@
+=========================
+ Using Rope As A Library
+=========================
+
+If you need other features, send a feature request.  Have a look at
+`contributing.txt`_.
+
+
+.. contents:: Table of Contents
+
+
+Quick Start
+===========
+
+This section will help you get started as soon as possible.
+
+
+Making A Project
+----------------
+
+The first thing you should do is to make a project::
+
+  import rope.base.project
+
+
+  myproject = rope.base.project.Project('/path/to/myproject')
+
+It's good to know that:
+
+* A project is a folder in the file-system.
+* It can contain anything.
+* Rope searches for python modules and packages inside a project when
+  needed.
+* Refactorings only change files and folders inside the project that
+  has been passed to them.
+* Out of project modules that are imported from a module inside a
+  project are handled but never changed by refactorings.
+* Rope makes a rope folder inside projects.  By default the name of
+  this folder is ``.ropeproject`` but that can be changed using the
+  constructor's `ropefolder` parameter (passing `None` will prevent
+  rope from making this folder).
+* Rope uses ``.ropeproject`` folder for things like saving object
+  information and loading project configurations.
+* Project preferences can be configured by passing options to the
+  constructor or in ``.ropeproject/config.py``.  See the default
+  ``config.py``, `rope.base.default_config` module, for more
+  information.
+* All configurations that are available in the ``config.py`` file can
+  be specified as keyword parameters to `Project` constructor.  These
+  parameters override the ones in the ``config.py`` file.
+* Each project has a set of ignored resource patterns; You can use it
+  to tell rope to ignore files and folders matching certain patterns.
+* The ``.ropeproject`` folder can be safely copied in other clones of
+  a project if you don't want to lose your objectdb and history.
+
+
+Library Utilities
+-----------------
+
+The `rope.base.libutils` module provides tools for making using rope
+as a library easier.  We'll talk more about this module later.
+
+
+What Are These `Resource`\s?
+----------------------------
+
+In rope, files and folders in a project are accessed through
+`rope.base.resources.Resource` objects.  It has two subclasses `File`
+and `Folder`.  What we care about is that refactorings and `Change`\s
+(we'll talk about them later) use resources.
+
+In order to create a `Resource` for a path in a project we have two
+options.  The first approach uses the `Project` object (use
+`Project.get_resource()`_ method).  I prefer to describe the second
+approach since it needs less to know.
+
+We can use `libutils` module.  It has a function named
+`path_to_resource()`.  It takes a project and a path::
+
+  from rope.base import libutils
+
+  myresource = libutils.path_to_resource(myproject, '/path/to/resource')
+
+
+But this is only half of the answer.  Consider we have a resource.
+How can we know anything about it? The answer is to use its ``path``
+and ``real_path`` fields.  `Resource.real_path` is the absolute path
+of the resource in the file-system.  `Resource.path` field contains
+the address of a resource relative to project root (the same format as
+needed by `Project.get_resource()`_).
+
+
+Performing Refactorings
+-----------------------
+
+There are examples at the end of this document.  But as another
+example we'll extract a variable in a file.  First we need the
+`Resource` object that points to a file in a project::
+
+  resource = libutils.path_to_resource(myproject, '/path/to/my/module.py')
+
+So we can make our Refactoring class::
+
+  from rope.refactor.extract import ExtractVariable
+
+
+  extractor = ExtractVariable(myproject, resource, start, end)
+
+Where `start` and `end` are the offsets of the region to extract in
+resource.  Be careful when calculating the offsets.  Dos line-endings
+and multi-byte characters are considered to be only one character.
+This is actually easier for IDEs, since most GUI libraries do that
+when calculating offsets.
+
+Next, IDE's usually pop up a dialog for letting the user configure
+refactoring options like the name of the extracted variable.
+
+After that, we can calculate the changes::
+
+  changes = extractor.get_changes('extracted_variable')
+
+`changes` holds the changes this refactoring makes.  Calculating it
+might be time consuming; See `rope.base.taskhandle.TaskHandle`_
+section for measuring its progress or interrupting it.
+
+
+Previewing And Performing Changes
+---------------------------------
+
+As mentioned in the last section each refactoring returns a
+`rope.base.change.Change` object.  Now how can we know what it
+contains and how to perform it?
+
+*Previewing*:
+
+``str(changes)`` returns a short description of the changes.  You can
+use ``changes.get_description()`` to get a preview; it is useful when
+you don't care much about the format.  Otherwise you can use the
+``changes`` object directly.  See the documentation in
+`rope.base.change` module.
+
+*Performing*:
+
+The easiest way for performing the refactoring is to use
+`Project.do()`_ method::
+
+  myproject.do(changes)
+
+If you want to perform the changes yourself, you have two options.
+Note that the main reason for performing the changes manually is
+handling version control systems that are not supported by rope.
+
+The first approach is to use `rope.base.fscommands`_.  See `Writing A
+FileSystemCommands`_ section.  The changes can be performed as before
+using `Project.do()`.
+
+The other is to perform the changes manually based on the returned
+`changes` object (again see the documentation in `rope.base.change`
+module).  If this approach is used you cannot undo the refactoring
+using ``project.history.undo()``.
+
+*Updating Open Buffers In IDEs*:
+
+Usually editors need to reload the files changed by rope.  You can use
+``Change.get_changed_resources()`` to get the list of resources that
+need to be reloaded.
+
+
+Validating The Project
+----------------------
+
+When using rope as a library, you probably change the files in it in
+parallel (for example in IDEs).  To force rope to invalidate cached
+information about resources that have been removed or changed outside
+rope you should call `Project.validate()`_ method.  You can pass a
+resource to this method.  For example::
+
+  myproject.validate()
+
+validates all files and directories in the project.  So call this
+function every time you want use rope (before performing refactorings,
+for instance).
+
+
+Activating Static Object Analysis
+---------------------------------
+
+One of the greatest strengths of rope is its static object analysis,
+SOA.  You can perform SOA on a module using `PyCore.analyze_module()`
+method but performing SOA on a module is not cheap.  So I decided that
+the best time for performing SOA is when saving files and only
+performing it on changed scopes.
+
+But since rope is not notified about the changes the IDE performs, you
+should tell rope about the change.  You can do so by using
+`rope.base.libutils.report_change()`.  That is, whenever you want to
+change a module you can do something like::
+
+  # Do the actual writing
+  old_contents = read(path)
+  write(path, new_content)
+
+  # Inform rope about the change
+  libutils.report_change(myproject, path, old_contents)
+
+Where `read` and `write` stand for methods used for reading and
+writing files.
+
+
+Closing The Project
+-------------------
+
+`Project.close()`_ closes project open resources.  Always call this
+function when you don't need a project anymore::
+
+  myproject.close()
+
+
+`rope.base.project.Project`
+===========================
+
+You can create a project by::
+
+  project = Project(root_address)
+
+Where the `root_address` is the root folder of your project.
+
+A project has some useful fields.  `Project.address` is the address of
+the root folder of a project.  `Project.root` is a `Folder` object
+that points to that folder.
+
+
+`Project.get_resource()`
+------------------------
+
+You can use this method for getting a resource (that is file or
+folder) inside a project.  Uses ``'/'``s for separating directories.
+For instance ``project.get_resource('my_folder/my_file.txt')`` returns
+a `rope.base.resources.File` object that points to
+``${projectroot}/my_folder/my_file.txt`` file.
+
+Note that this method assumes the resource exists.  If it does not
+exist you can use `Project.get_file()` and `Project.get_folder()`
+methods.
+
+
+`Project.do()`
+--------------
+
+For committing changes returned by refactorings.
+
+
+`Project.history`
+-----------------
+
+A `rope.base.history.History` object.  You can use its `undo` and
+`redo` methods for undoing or redoing changes.  Note that you can use
+it only if you have committed your changes using rope.
+
+
+`Project.validate()`
+--------------------
+
+When using rope as a library you probably change the files in that
+project in parallel (for example in IDEs).  To force rope to
+invalidate cached information about resources that have been
+removed or changed outside rope you should call `Project.validate`.
+You should pass a resource to this method.  For example::
+
+  project.validate(project.root)
+
+validates all files and directories in the project.
+
+
+`Project.close()`
+-----------------
+
+Closes project open resources.  Always call this function when you
+don't need a project anymore.  Currently it closes the files used for
+storing object information and project history.  Since some parts of
+these files are in memory for efficiency not closing a project might
+put them in an inconsistent state.
+
+
+`rope.base.fscommands`
+----------------------
+
+The `rope.base.fscommands` module implements the basic file system
+operations that rope needs to perform.  The main reason for the
+existence of this module is supporting version control systems.  Have
+a look at `FileSystemCommands` and `SubversionCommands` in the same
+module.  If you need other version control systems you can write a new
+class that provides this interface.  `rope.base.project.Project`
+accepts a ``fscommands`` argument.  You can use this argument to force
+rope to use your new class.
+
+
+``.ropeproject`` Folder
+-----------------------
+
+From version ``0.5``, rope makes a ``.ropeproject`` folder in the
+project by default for saving project configurations and data.  The
+name of this folder is passed to the constructor if you want to change
+that.  Also you can force rope not to make such a folder by passing
+`None`.
+
+If such a folder exists rope loads the ``config.py`` file in that
+folder.  It might also use it for storing object information and
+history.
+
+
+`rope.base.pycore.PyCore`
+=========================
+
+Provides useful methods for managing python modules and packages.
+Each project has a `PyCore` that can be accessed using
+`Project.pycore` attribute.
+
+`PyCore.run_module()` runs a resource.  When running, it collects type
+information to do dynamic object inference.  For this reason modules
+run much slower.
+
+Also `Pycore.analyze_module()` collects object information for a
+module.  The collected information can be used to enhance rope's
+static object inference.
+
+
+`rope.base.taskhandle.TaskHandle`
+=================================
+
+Can be used for stopping and monitoring the progress of time consuming
+tasks like some of refactorings.  `Project.do()` and
+`Refactoring.get_changes()` of most refactorings take a keyword
+parameter called ``task_handle``.  You can pass a `TaskHandle` object
+to them.  A `TaskHandle` can be used for interrupting or observing a
+task.
+
+Always pass ``task_handle`` as keyword argument; it will always be the
+last argument and new arguments of the refactoring are added before
+it.
+
+A task might consist of a few `JobSet`\s.  Each `JobSet` does a few
+jobs.  For instance calculating the changes for renaming a method in a
+class hierarchy has two job sets; We need to find the classes for
+constructing the class hierarchy and then we need to change the
+occurrences.
+
+The `TaskHandle.current_jobset()` returns the most recent `JobSet` or
+`None` if none has been started.  You can use the methods of `JobSet`
+for obtaining information about the current job.  So you might want to
+do something like::
+
+  import rope.base.taskhandle
+
+
+  handle = rope.base.taskhandle.TaskHandle("Test Task")
+
+  def update_progress():
+      jobset = handle.current_jobsets()
+      if jobset:
+          text = ''
+          # getting current job set name
+          if jobset.get_name() is not None:
+              text += jobset.get_name()
+          # getting active job name
+          if jobset.get_active_job_name() is not None:
+              text += ' : ' + jobset.get_active_job_name()
+          # adding done percent
+          percent = jobset.get_percent_done()
+          if percent is not None:
+              text += ' ... %s percent done' % percent
+          print text
+
+  handle.add_observer(update_progress)
+
+  changes = renamer.get_changes('new_name', task_handle=handle)
+
+Also you can use something like this for stopping the task::
+
+  def stop():
+      handle.stop()
+
+After calling ``stop()``, the thread that is executing the task will
+be interrupted by a `rope.base.exceptions.InterruptedTaskError`
+exception.
+
+
+Refactorings
+============
+
+Have a look at `rope.refactor` package and its sub-modules.  For
+example for performing a move refactoring you can create a
+`Move` object like this::
+
+  mover = Move(project, resource, offset)
+
+Where `resource` and `offset` is the location to perform the
+refactoring.
+
+Then you can commit the changes by it using `get_changes()` method::
+
+  project.do(mover.get_changes(destination))
+
+Where `destination` module/package is the destination resource for
+move refactoring.  Other refactorings classes have a similar
+interface.
+
+
+List Of Refactorings
+--------------------
+
+Here is the list of refactorings rope provides.  Note that this list
+might be out of date.  For more information about these refactoring
+see pydocs in their modules and the unit-tests in the
+``ropetest/refactor/`` folder.
+
+* `rope.refactor.rename`:
+  Rename something in the project.  See the example below.
+
+* `rope.refactor.move`:
+  Move a python element in the project.
+
+* `rope.refactor.restructure`:
+  Restructure code.  See the example below.
+
+* `rope.refactor.extract`:
+  Extract methods/variables.
+
+* `rope.refactor.inline`:
+  Inline occurrences of a method/variable/parameter.
+
+* `rope.refactor.usefunction`:
+  Try to use a function wherever possible.
+
+* `rope.refactor.method_object`:
+  Transform a function or a method to a method object.
+
+* `rope.refactor.change_signature`:
+  Change the signature of a function/method.
+
+* `rope.refactor.introduce_factory`:
+  Introduce a factory for a class and changes all constructors to use
+  it.
+
+* `rope.refactor.introduce_parameter`:
+  Introduce a parameter in a function.
+
+* `rope.refactor.encapsulate_field`:
+  Generate a getter/setter for a field and changes its occurrences to
+  use them.
+
+* `rope.refactor.localtofield`:
+  Change a local variable to field
+
+* `rope.refactor.topackage`:
+  Transform a module to a package with the same name.
+
+* `rope.refactor.importutils`:
+  Perform actions like organize imports.
+
+
+Refactoring Resources Parameter
+-------------------------------
+
+Some refactorings, restructure and find occurrences accept an argument
+called ``resources``.  If it is a list of `File`\s, all other
+resources in the project are ignored and the refactoring only analyzes
+them; if it is `None` all python modules in the project will be
+analyzed.  Using this parameter, IDEs can let the user limit the files
+on which a refactoring should be applied.
+
+
+Examples
+========
+
+Rename
+------
+
+Using rename refactoring::
+
+  # Creating a project
+  >>> from rope.base.project import Project
+  >>> project = Project('.')
+
+  # Working with files to create a module
+  >>> mod1 = project.root.create_file('mod1.py')
+  >>> mod1.write('a_var = 10\n')
+
+  # Alternatively you can use `generate` module.
+  # Creating modules and packages using `generate` module
+  >>> from rope.contrib import generate
+  >>> pycore = project.pycore
+  >>> pkg = generate.create_package(project, 'pkg')
+  >>> mod2 = generate.create_module(project, 'mod2', pkg)
+  >>> mod2.write('import mod1\nprint mod1.a_var\n')
+
+  # We can use `PyCore.find_module` for finding modules, too
+  >>> assert mod2 == pycore.find_module('pkg.mod2')
+
+  # Performing rename refactoring on `mod1.a_var`
+  >>> from rope.refactor.rename import Rename
+  >>> changes = Rename(project, mod1, 1).get_changes('new_var')
+  >>> project.do(changes)
+  >>> mod1.read()
+  u'new_var = 10\n'
+  >>> mod2.read()
+  u'import mod1\nprint mod1.new_var\n'
+
+  # Undoing rename refactoring
+  >>> project.history.undo()
+  ...
+  >>> mod1.read()
+  u'a_var = 10\n'
+  >>> mod2.read()
+  u'import mod1\nprint mod1.a_var\n'
+
+  # Cleaning up
+  >>> pkg.remove()
+  >>> mod1.remove()
+  >>> project.close()
+
+
+Restructuring
+-------------
+
+The example for replacing occurrences of our `pow` function to ``**``
+operator (see the restructuring section of `overview.txt`_)::
+
+  # Setting up the project
+  >>> from rope.base.project import Project
+  >>> project = Project('.')
+
+  >>> mod1 = project.root.create_file('mod1.py')
+  >>> mod1.write('def pow(x, y):\n    result = 1\n'
+  ...            '    for i in range(y):\n        result *= x\n'
+  ...            '    return result\n')
+  >>> mod2 = project.root.create_file('mod2.py')
+  >>> mod2.write('import mod1\nprint(mod1.pow(2, 3))\n')
+
+  >>> from rope.refactor import restructure
+
+  >>> pattern = '${pow_func}(${param1}, ${param2})'
+  >>> goal = '${param1} ** ${param2}'
+  >>> args = {'pow_func': 'name=mod1.pow'}
+
+  >>> restructuring = restructure.Restructure(project, pattern, goal, args)
+
+  >>> project.do(restructuring.get_changes())
+  >>> mod2.read()
+  u'import mod1\nprint(2 ** 3)\n'
+  
+  # Cleaning up
+  >>> mod1.remove()
+  >>> mod2.remove()
+  >>> project.close()
+
+
+See code documentation and test suites for more information.
+
+.. _overview.txt: overview.html
+.. _contributing.txt: contributing.html
+
+
+Other Topics
+============
+
+
+Writing A `FileSystemCommands`
+------------------------------
+
+The `get_changes()` method of refactoring classes return a
+`rope.base.change.Change` object.  You perform these changes by
+calling `Project.do()`.  But as explained above some IDEs need to
+perform the changes themselves.
+
+Every change to file-system in rope is commited using an object that
+provides `rope.base.fscommands.FileSystemCommands` interface.  As
+explained above in `rope.base.fscommands`_ section, rope uses this
+interface to handle different VCSs.
+
+You can implement your own fscommands object::
+
+  class MyFileSystemCommands(object):
+
+    def create_file(self, path):
+        """Create a new file"""
+        # ...
+
+    def create_folder(self, path):
+        """Create a new folder"""
+        # ...
+
+    def move(self, path, new_location):
+        """Move resource at `path` to `new_location`"""
+        # ...
+
+    def remove(self, path):
+        """Remove resource"""
+        # ...
+
+    def write(self, path, data):
+        """Write `data` to file at `path`"""
+        # ...
+
+And you can create a project like this::
+
+  my_fscommands = MyFileSystemCommands()
+  project = rope.base.project.Project('~/myproject',
+                                      fscommands=my_fscommands)
+
+
+`rope.contrib.codeassist`
+-------------------------
+
+The `rope.contrib` package contains modules that use rope base parts
+and provide useful features.  `rope.contrib.codeassist` module can
+be used in IDEs::
+
+  from rope.ide import codeassist
+
+
+  # Get the proposals; you might want to pass a Resource
+  proposals = codeassist.code_assist(project, source_code, offset)
+  # Sorting proposals; for changing the order see pydoc
+  proposals = codeassist.sorted_proposals(proposals)
+
+  # Where to insert the completions
+  starting_offset = codeassist.starting_offset(source_code, offset)
+
+  # Applying a proposal
+  proposal = proposals[x]
+  replacement = proposal.name
+
+  new_source_code = (source_code[:starting_offset] +
+                     replacement + source_code[offset:])
+
+`maxfixes` parameter of `code_assist` decides how many syntax errors
+to fix.  The default value is one.  For instance::
+
+  def f():
+      g(my^
+
+  myvariable = None
+
+  def g(p):
+      invalid syntax ...
+
+will report `myvariable`, only if `maxfixes` is bigger than 1.
+
+`later_locals`, if `True`, forces rope to propose names that are
+defined later in current scope.  It is `True` by default.  For
+instance::
+
+  def f():
+      my^
+      myvariable = None
+
+will not report `myvariable`, if `later_locals` is False.
+
+See pydocs and source code for more information (other functions in
+this module might be interesting, too; like `get_doc`,
+`get_definition_location`).
+
+
+`rope.contrib.findit`
+---------------------
+
+`findit` module provides `find_occurrences()` for finding occurrences
+of a name.  Also `find_implementations()` function finds the places in
+which a method is overridden.
+
+
+`rope.contrib.autoimport`
+-------------------------
+
+This module can be used to find the modules that provide a name.  IDEs
+can use this module to auto-import names.  `AutoImport.get_modules()`
+returns the list of modules with the given global name.
+`AutoImport.import_assist()` tries to find the modules that have a
+global name that starts with the given prefix.
+
+
+Cross-Project Refactorings
+--------------------------
+
+`rope.refactor.multiproject` can be used to perform a refactoring
+across multiple projects.
+
+Usually refactorings have a main project.  That is the project that
+contains the definition of the changing python name.  Other projects
+depend on the main one and uses of the changed name in them should be
+updated.
+
+Each refactoring changes only one project (the project passed to its
+constructor).  But we can use `MultiProjectRefactoring` proxy to
+perform a refactoring on other projects, too.
+
+First we need to create a multi-project refactoring constructor.  As
+an example consider we want to perform a rename refactoring::
+
+  from rope.refactor import multiproject, rename
+
+
+  CrossRename = multiproject.MultiProjectRefactoring(rename.Rename,
+                                                     projects)
+
+
+Here `projects` is the list of dependant projects; it does not include
+the main project.  The first argument is the refactoring class (such
+as `Rename`) or factory function (like `create_move`).
+
+Next we can construct the refactoring::
+
+  renamer = CrossRename(project, resource, offset)
+
+We create the rename refactoring as we do for normal refactorings.
+Note that `project` is the main project.
+
+As mentioned above, other projects use the main project; rope
+automatically adds the main project to the python path of other
+projects.
+
+Finally we can calculate the changes.  But instead of calling
+`get_changes()` (which returns main project changes, only), we can
+call `get_all_changes()` with the same arguments.  It returns a list
+of ``(project, changes)`` tuples.  You can perform them manually by
+calling ``project.do(changes)`` for each tuple or use
+`multiproject.perform()`::
+
+  project_and_changes = renamer.get_all_changes('newname')
+
+  multiproject.perform(project_and_changes)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/docs/overview.txt	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,1116 @@
+===============
+ Rope Overview
+===============
+
+
+The purpose of this file is to give an overview of some of rope's
+features.  It is incomplete.  And some of the features shown here are
+old and do not show what rope can do in extremes.  So if you really
+want to feel the power of rope try its features and see its unit
+tests.
+
+This file is more suitable for the users.  Developers who plan to use
+rope as a library might find library.txt_ more useful.
+
+.. contents:: Table of Contents
+.. _library.txt: library.html
+
+
+``.ropeproject`` Folder
+=======================
+
+Rope uses a folder inside projects for holding project configuration
+and data.  Its default name is ``.ropeproject``, but it can be
+changed (you can even tell rope not to create this folder).
+
+Currently it is used for things such as:
+
+* There is a ``config.py`` file in this folder in which you can change
+  project configurations.  Have look at the default ``config.py`` file
+  (is created when it does not exist) for more information.
+* It can be used for saving project history, so that the next time you
+  open the project you can undo past changes.
+* It can be used for saving object information to help rope object
+  inference.
+* It can be used for saving global names cache which is used in
+  auto-import.
+
+You can change what to save and what not to in the ``config.py`` file.
+
+
+Refactorings
+============
+
+This section shows some random refactorings that you can perform using
+rope.
+
+
+Renaming Attributes
+-------------------
+
+Consider we have::
+
+  class AClass(object):
+
+      def __init__(self):
+          self.an_attr = 1
+
+      def a_method(self, arg):
+          print self.an_attr, arg
+
+  a_var = AClass()
+  a_var.a_method(a_var.an_attr)
+
+After renaming ``an_attr`` to ``new_attr`` and ``a_method`` to
+``new_method`` we'll have::
+
+  class AClass(object):
+
+      def __init__(self):
+          self.new_attr = 1
+
+      def new_method(self, arg):
+          print self.new_attr, arg
+
+  a_var = AClass()
+  a_var.new_method(a_var.new_attr)
+
+
+Renaming Function Keyword Parameters
+------------------------------------
+
+On::
+
+  def a_func(a_param):
+      print a_param
+
+  a_func(a_param=10)
+  a_func(10)
+
+performing rename refactoring on any occurrence of ``a_param`` will
+result in::
+
+  def a_func(new_param):
+      print new_param
+
+  a_func(new_param=10)
+  a_func(10)
+
+
+Renaming modules
+----------------
+
+Consider the project tree is something like::
+
+  root/
+    mod1.py
+    mod2.py
+
+``mod1.py`` contains::
+
+  import mod2
+  from mod2 import AClass
+
+  mod2.a_func()
+  a_var = AClass()
+
+After performing rename refactoring one of the ``mod2`` occurrences in
+`mod1` we'll get::
+
+  import newmod
+  from newmod import AClass
+
+  newmod.a_func()
+  a_var = AClass()
+
+and the new project tree would be::
+
+  root/
+    mod1.py
+    newmod.py
+
+
+Renaming Occurrences In Strings And Comments
+--------------------------------------------
+
+You can tell rope to rename all occurrences of a name in comments and
+strings.  This can be done by passing ``docs=True`` to
+`Rename.get_changes()` method.  Rope renames names in comments and
+strings only where the name is visible.  For example in::
+
+  def f():
+      a_var = 1
+      # INFO: I'm printing `a_var`
+      print 'a_var = %s' % a_var
+
+  # f prints a_var
+
+after we rename the `a_var` local variable in `f()` to `new_var` we
+would get::
+
+  def f():
+      new_var = 1
+      # INFO: I'm printing `new_var`
+      print 'new_var = %s' % new_var
+
+  # f prints a_var
+
+This makes it safe to assume that this option does not perform wrong
+renames most of the time.
+
+This also changes occurrences inside evaluated strings::
+
+  def func():
+      print 'func() called'
+
+  eval('func()')
+
+After renaming `func` to `newfunc` we should have::
+
+  def newfunc():
+      print 'newfunc() called'
+
+  eval('newfunc()')
+
+
+Rename When Unsure
+------------------
+
+This option tells rope to rename when it doesn't know whether it is an
+exact match or not.  For example after renaming `C.a_func` when the
+'rename when unsure' option is set in::
+
+  class C(object):
+
+      def a_func(self):
+          pass
+
+  def a_func(arg):
+      arg.a_func()
+
+  C().a_func()
+  
+we would have::
+
+  class C(object):
+
+      def new_func(self):
+          pass
+
+  def a_func(arg):
+      arg.new_func()
+
+  C().new_func()
+
+Note that the global `a_func` was not renamed because we are sure that
+it is not a match.  But when using this option there might be some
+unexpected renames.  So only use this option when the name is almost
+unique and is not defined in other places.
+
+Move Method Refactoring
+-----------------------
+
+It happens when you perform move refactoring on a method of a class.
+In this refactoring, a method of a class is moved to the class of one
+of its attributes.  The old method will call the new method.  If you
+want to change all of the occurrences of the old method to use the new
+method you can inline it afterwards.
+
+For instance if you perform move method on `a_method` in::
+
+  class A(object):
+      pass
+
+  class B(object):
+
+      def __init__(self):
+          self.attr = A()
+
+      def a_method(self):
+          pass
+
+  b = B()
+  b.a_method()
+
+You will be asked for the destination field and the name of the new
+method.  If you use ``attr`` and ``new_method`` in these fields
+and press enter, you'll have::
+      
+  class A(object):
+
+      def new_method(self):
+          pass
+
+  class B(object):
+
+      def __init__(self):
+          self.attr = A()
+
+      def a_method(self):
+          return self.attr.new_method()
+
+
+  b = B()
+  b.a_method()
+
+Now if you want to change the occurrences of `B.a_method()` to use
+`A.new_method()`, you can inline `B.a_method()`::
+
+  class A(object):
+
+      def new_method(self):
+          pass
+
+  class B(object):
+
+      def __init__(self):
+          self.attr = A()
+
+  b = B()
+  b.attr.new_method()
+
+
+Moving Fields
+-------------
+
+Rope does not have a separate refactoring for moving fields.  Rope's
+refactorings are very flexible, though.  You can use the rename
+refactoring to move fields.  For instance::
+
+  class A(object):
+      pass
+
+  class B(object):
+
+      def __init__(self):
+          self.a = A()
+          self.attr = 1
+
+  b = B()
+  print(b.attr)
+
+consider we want to move `attr` to `A`.  We can do that by renaming `attr`
+to `a.attr`::
+  
+  class A(object):
+      pass
+
+  class B(object):
+
+      def __init__(self):
+          self.a = A()
+          self.a.attr = 1
+
+  b = B()
+  print(b.a.attr)
+
+You can move the definition of `attr` manually.
+
+
+Extract Method
+--------------
+
+In these examples ``${region_start}`` and ``${region_end}`` show the
+selected region for extraction::
+
+  def a_func():
+      a = 1
+      b = 2 * a
+      c = ${region_start}a * 2 + b * 3${region_end}
+
+After performing extract method we'll have::
+
+  def a_func():
+      a = 1
+      b = 2 * a
+      c = new_func(a, b)
+
+  def new_func(a, b):
+      return a * 2 + b * 3
+
+For multi-line extractions if we have::
+
+  def a_func():
+      a = 1
+      ${region_start}b = 2 * a
+      c = a * 2 + b * 3${region_end}
+      print b, c
+
+After performing extract method we'll have::
+
+  def a_func():
+      a = 1
+      b, c = new_func(a)
+      print b, c
+
+  def new_func(a):
+      b = 2 * a
+      c = a * 2 + b * 3
+      return b, c
+
+
+Extracting Similar Expressions/Statements
+-----------------------------------------
+
+When performing extract method or local variable refactorings you can
+tell rope to extract similar expressions/statements.  For instance
+in::
+
+  if True:
+      x = 2 * 3
+  else:
+      x = 2 * 3 + 1
+
+Extracting ``2 * 3`` will result in::
+
+  six = 2 * 3
+  if True:
+      x = six
+  else:
+      x = six + 1
+
+
+Extract Method In staticmethods/classmethods
+--------------------------------------------
+
+The extract method refactoring has been enhanced to handle static and
+class methods better.  For instance in::
+
+  class A(object):
+
+      @staticmethod
+      def f(a):
+          b = a * 2
+
+if you extract ``a * 2`` as a method you'll get::
+
+  class A(object):
+
+      @staticmethod
+      def f(a):
+          b = A.twice(a)
+
+      @staticmethod
+      def twice(a):
+          return a * 2
+
+
+Inline Method Refactoring
+-------------------------
+
+Inline method refactoring can add imports when necessary.  For
+instance consider ``mod1.py`` is::
+
+  import sys
+
+
+  class C(object):
+      pass
+
+  def do_something():
+      print sys.version
+      return C()
+
+and ``mod2.py`` is::
+
+  import mod1
+
+
+  c = mod1.do_something()
+
+After inlining `do_something`, ``mod2.py`` would be::
+
+  import mod1
+  import sys
+
+
+  print sys.version
+  c = mod1.C()
+
+Rope can inline methods, too::
+
+  class C(object):
+
+      var = 1
+
+      def f(self, p):
+	  result = self.var + pn
+	  return result
+
+
+  c = C()
+  x = c.f(1)
+
+After inlining `C.f()`, we'll have::
+
+  class C(object):
+
+      var = 1
+
+  c = C()
+  result = c.var + pn
+  x = result
+
+As another example we will inline a `classmethod`::
+
+  class C(object):
+      @classmethod
+      def say_hello(cls, name):
+          return 'Saying hello to %s from %s' % (name, cls.__name__)
+  hello = C.say_hello('Rope')
+
+Inlining `say_hello` will result in::
+
+  class C(object):
+      pass
+  hello = 'Saying hello to %s from %s' % ('Rope', C.__name__)
+
+
+Inlining Parameters
+-------------------
+
+`rope.refactor.inline.create_inline()` creates an `InlineParameter`
+object when performed on a parameter.  It passes the default value of
+the parameter wherever its function is called without passing it.  For
+instance in::
+
+  def f(p1=1, p2=1):
+      pass
+
+  f(3)
+  f()
+  f(3, 4)
+
+after inlining p2 parameter will have::
+
+  def f(p1=1, p2=1):
+      pass
+
+  f(3, 2)
+  f(p2=2)
+  f(3, 4)
+
+
+Use Function Refactoring
+------------------------
+
+It tries to find the places in which a function can be used and
+changes the code to call it instead.  For instance if mod1 is::
+
+  def square(p):
+      return p ** 2
+
+  my_var = 3 ** 2
+
+
+and mod2 is::
+
+  another_var = 4 ** 2
+
+if we perform "use function" on square function, mod1 will be::
+
+  def square(p):
+      return p ** 2
+
+  my_var = square(3)
+
+and mod2 will be::
+
+  import mod1
+  another_var = mod1.square(4)
+
+
+Automatic Default Insertion In Change Signature
+-----------------------------------------------
+
+The `rope.refactor.change_signature.ArgumentReorderer` signature
+changer takes a parameter called ``autodef``.  If not `None`, its
+value is used whenever rope needs to insert a default for a parameter
+(that happens when an argument without default is moved after another
+that has a default value).  For instance in::
+
+  def f(p1, p2=2):
+      pass
+
+if we reorder using::
+
+  changers = [ArgumentReorderer([1, 0], autodef='1')]
+
+will result in::
+
+  def f(p2=2, p1=1):
+      pass
+
+
+Sorting Imports
+---------------
+
+Organize imports sorts imports, too.  It does that according to
+:PEP:`8`::
+
+  [__future__ imports]
+
+  [standard imports]
+
+  [third-party imports]
+
+  [project imports]
+
+
+  [the rest of module]
+
+
+Handling Long Imports
+---------------------
+
+``Handle long imports`` command trys to make long imports look better by
+transforming ``import pkg1.pkg2.pkg3.pkg4.mod1`` to ``from
+pkg1.pkg2.pkg3.pkg4 import mod1``.  Long imports can be identified
+either by having lots of dots or being very long.  The default
+configuration considers imported modules with more than 2 dots or with
+more than 27 characters to be long.
+
+
+Stoppable Refactorings
+----------------------
+
+Some refactorings might take a long time to finish (based on the size
+of your project).  The `get_changes()` method of these refactorings
+take a parameter called `task_handle`.  If you want to monitor or stop
+these refactoring you can pass a `rope.refactor.
+taskhandle.TaskHandle` to this method.  See `rope.refactor.taskhandle`
+module for more information.
+
+
+Basic Implicit Interfaces
+-------------------------
+
+Implicit interfaces are the interfaces that you don't explicitly
+define; But you expect a group of classes to have some common
+attributes.  These interfaces are very common in dynamic languages;
+Since we only have implementation inheritance and not interface
+inheritance.  For instance::
+
+  class A(object):
+
+      def count(self):
+          pass
+
+  class B(object):
+
+      def count(self):
+          pass
+
+  def count_for(arg):
+      return arg.count()
+
+  count_for(A())
+  count_for(B())
+
+Here we know that there is an implicit interface defined by the
+function `count_for` that provides `count()`.  Here when we rename
+`A.count()` we expect `B.count()` to be renamed, too.  Currently rope
+supports a basic form of implicit interfaces.  When you try to rename
+an attribute of a parameter, rope renames that attribute for all
+objects that have been passed to that function in different call
+sites.  That is renaming the occurrence of `count` in `count_for`
+function to `newcount` will result in::
+
+  class A(object):
+
+      def newcount(self):
+          pass
+
+  class B(object):
+
+      def newcount(self):
+          pass
+
+  def count_for(arg):
+      return arg.newcount()
+
+  count_for(A())
+  count_for(B())
+
+This also works for change method signature.  Note that this feature
+relies on rope's object analysis mechanisms to find out the parameters
+that are passed to a function.
+
+
+Restructurings
+--------------
+
+`rope.refactor.restructure` can be used for performing restructurings.
+A restructuring is a program transformation; not as well defined as
+other refactorings like rename.  In this section, we'll see some
+examples.  After this example you might like to have a look at:
+
+* `rope.refactor.restructure` for more examples and features not
+  described here like adding imports to changed modules.
+* `rope.refactor.wildcards` for an overview of the arguments the
+  default wildcard supports.
+
+Finally, restructurings can be improved in many ways (for instance
+adding new wildcards).  You might like to discuss your ideas in the
+mailing list.
+
+
+Example 1
+'''''''''
+
+In its basic form we have a pattern and a goal.  Consider we were not
+aware of the ``**`` operator and wrote our own ::
+
+  def pow(x, y):
+      result = 1
+      for i in range(y):
+          result *= x
+      return result
+
+  print pow(2, 3)
+
+Now that we know ``**`` exists we want to use it wherever `pow` is
+used (there might be hundreds of them!).  We can use a pattern like::
+
+  pattern: pow(${param1}, ${param2})
+
+Goal can be something like::
+
+  goal: ${param1} ** ${param2}
+
+Note that ``${...}`` can be used to match expressions.  By default
+every expression at that point will match.
+
+You can use the matched names in goal and they will be replaced with
+the string that was matched in each occurrence.  So the outcome of our
+restructuring will be::
+
+  def pow(x, y):
+      result = 1
+      for i in range(y):
+          result *= x
+      return result
+
+  print 2 ** 3
+
+It seems to be working but what if `pow` is imported in some module or
+we have some other function defined in some other module that uses the
+same name and we don't want to change it.  Wildcard arguments come to
+rescue.  Wildcard arguments is a mapping; Its keys are wildcard names
+that appear in the pattern (the names inside ``${...}``).
+
+The values are the parameters that are passed to wildcard matchers.
+The arguments a wildcard takes is based on its type.
+
+For checking the type of a wildcard, we can pass ``type=value`` as an
+argument; ``value`` should be resolved to a python variable (or
+reference).  For instance for specifying `pow` in this example we can
+use `mod.pow`.  As you see, this string should start from module name.
+For referencing python builtin types and functions you can use
+`__builtin__` module (for instance `__builtin__.int`).
+
+For solving the mentioned problem, we change our `pattern`.  But
+`goal` remains the same::
+
+  pattern: ${pow_func}(${param1}, ${param2})
+  goal: ${param1} ** ${param2}
+
+Consider the name of the module containing our `pow` function is
+`mod`.  ``args`` can be::
+
+  pow_func: name=mod.pow
+
+If we need to pass more arguments to a wildcard matcher we can use
+``,`` to separate them.  Such as ``name: type=mod.MyClass,exact``.
+
+This restructuring handles aliases; like in::
+
+  mypow = pow
+  result = mypow(2, 3)
+
+Transforms into::
+
+  mypow = pow
+  result = 2 ** 3
+
+If we want to ignore aliases we can pass ``exact`` as another wildcard
+argument::
+
+  pattern: ${pow}(${param1}, ${param2})
+  goal: ${param1} ** ${param2}
+  args: pow: name=mod.pow, exact
+
+``${name}``, by default, matches every expression at that point; if
+``exact`` argument is passed to a wildcard only the specified name
+will match (for instance, if ``exact`` is specified , ``${name}``
+matches ``name`` and ``x.name`` but not ``var`` nor ``(1 + 2)`` while
+a normal ``${name}`` can match all of them).
+
+For performing this refactoring using rope library see `library.txt`_.
+
+
+Example 2
+'''''''''
+
+As another example consider::
+
+  class A(object):
+
+      def f(self, p1, p2):
+          print p1
+          print p2
+
+
+  a = A()
+  a.f(1, 2)
+
+Later we decide that `A.f()` is doing too much and we want to divide
+it to `A.f1()` and `A.f2()`::
+
+  class A(object):
+
+      def f(self, p1, p2):
+          print p1
+          print p2
+
+      def f1(self, p):
+          print p
+
+      def f2(self, p):
+          print p
+
+
+  a = A()
+  a.f(1, 2)
+
+But who's going to fix all those nasty occurrences (actually this
+situation can be handled using inline method refactoring but this is
+just an example; consider inline refactoring is not implemented yet!).
+Restructurings come to rescue::
+
+  pattern: ${inst}.f(${p1}, ${p2})
+  goal:
+   ${inst}.f1(${p1})
+   ${inst}.f2(${p2})
+  
+  args:
+   inst: type=mod.A
+
+After performing we will have::
+
+  class A(object):
+
+      def f(self, p1, p2):
+          print p1
+          print p2
+
+      def f1(self, p):
+          print p
+
+      def f2(self, p):
+          print p
+
+
+  a = A()
+  a.f1(1)
+  a.f2(2)
+
+
+Example 3
+'''''''''
+
+If you like to replace every occurrences of ``x.set(y)`` with ``x =
+y`` when x is an instance of `mod.A` in::
+
+  from mod import A
+
+  a = A()
+  b = A()
+  a.set(b)
+
+We can perform a restructuring with these information::
+
+  pattern: ${x}.set(${y})
+  goal: ${x} = ${y}
+
+  args: x: type=mod.A
+
+After performing the above restructuring we'll have::
+
+  from mod import A
+
+  a = A()
+  b = A()
+  a = b
+
+Note that ``mod.py`` contains something like::
+
+  class A(object):
+
+      def set(self, arg):
+          pass
+
+Issues
+''''''
+
+Pattern names can appear only at the start of an expression.  For
+instance ``var.${name}`` is invalid.  These situations can usually be
+fixed by specifying good checks, for example on the type of `var` and
+using a ``${var}.name``.
+
+
+Object Inference
+================
+
+This section is a bit out of date.  Static object inference can do
+more than described here (see unittests).  Hope to update this
+someday!
+
+
+Static Object Inference
+-----------------------
+
+::
+
+  class AClass(object):
+
+      def __init__(self):
+          self.an_attr = 1
+
+      def call_a_func(self):
+          return a_func()
+
+  def a_func():
+      return AClass()
+
+  a_var = a_func()
+  #a_var.${codeassist}
+
+  another_var = a_var
+  #another_var.${codeassist}
+  #another_var.call_a_func().${codeassist}
+
+
+Basic support for builtin types::
+
+  a_list = [AClass(), AClass()]
+  for x in a_list:
+      pass
+      #x.${codeassist}
+  #a_list.pop().${codeassist}
+
+  a_dict = ['text': AClass()]
+  for key, value in a_dict.items():
+      pass
+      #key.${codeassist}
+      #value.${codeassist}
+
+Enhanced static returned object inference::
+
+    class C(object):
+
+        def c_func(self):
+            return ['']
+
+    def a_func(arg):
+        return arg.c_func()
+
+    a_var = a_func(C())
+
+Here rope knows that the type of a_var is a `list` that holds `str`\s.
+
+Supporting generator functions::
+
+  class C(object):
+      pass
+
+  def a_generator():
+      yield C()
+
+
+  for c in a_generator():
+      a_var = c
+
+Here the objects `a_var` and `c` hold are known.
+
+Rope collects different types of data during SOA, like per name data
+for builtin container types::
+
+  l1 = [C()]
+  var1 = l1.pop()
+
+  l2 = []
+  l2.append(C())
+  var2 = l2.pop()
+
+Here rope can easily infer the type of `var1`.  But for knowing the
+type of `var2`, it needs to analyze the items inserted into `l2` which
+might happen in other modules.  Rope can do that by running SOA on
+that module.
+
+You might be wondering is there any reason for using DOA instead of
+SOA.  The answer is that DOA might be more accurate and handles
+complex and dynamic situations.  For example in::
+
+  def f(arg):
+      return eval(arg)
+
+  a_var = f('C')
+
+SOA can no way conclude the object `a_var` holds but it is really
+trivial for DOA.  What's more SOA only analyzes calls in one module
+while DOA analyzes any call that happens when running a module.  That
+is, for achieving the same result as DOA you might need to run SOA on
+more than one module and more than once (not considering dynamic
+situations.) One advantage of SOA is that it is much faster than DOA.
+
+
+Dynamic Object Analysis
+-----------------------
+
+`PyCore.run_module()` runs a module and collects object information if
+``perform_doa`` project config is set.  Since as the program runs rope
+gathers type information, the program runs much slower.  After the
+program is run, you can get better code assists and some of the
+refactorings perform much better.
+
+``mod1.py``::
+
+  def f1(param):
+      pass
+      #param.${codeassist}
+      #f2(param).${codeassist}
+
+  def f2(param):
+      #param.${codeassist}
+      return param
+
+Using code assist in specified places does not give any information
+and there is actually no information about the return type of `f2` or
+`param` parameter of `f1`.
+
+``mod2.py``::
+
+  import mod1
+
+  class A(object):
+
+      def a_method(self):
+          pass
+
+  a_var = A()
+  mod1.f1(a_var)
+
+Retry those code assists after performing DOA on `mod2` module.
+
+
+Builtin Container Types
+'''''''''''''''''''''''
+
+Builtin types can be handled in a limited way, too::
+
+  class A(object):
+
+      def a_method(self):
+          pass
+
+  def f1():
+      result = []
+      result.append(A())
+      return result
+
+  returned = f()
+  #returned[0].${codeassist}
+
+Test the the proposed completions after running this module.
+
+
+Guessing Function Returned Value Based On Parameters
+----------------------------------------------------
+
+``mod1.py``::
+
+  class C1(object):
+
+      def c1_func(self):
+          pass
+
+  class C2(object):
+
+      def c2_func(self):
+          pass
+
+
+  def func(arg):
+      if isinstance(arg, C1):
+          return C2()
+      else:
+          return C1()
+
+  func(C1())
+  func(C2())
+
+After running `mod1` either SOA or DOA on this module you can test:
+
+``mod2.py``::
+
+  import mod1
+
+  arg = mod1.C1()
+  a_var = mod1.func(arg)
+  a_var.${codeassist}
+  mod1.func(mod1.C2()).${codeassist}
+
+
+Automatic SOA
+-------------
+
+When turned on, it analyzes the changed scopes of a file when saving
+for obtaining object information; So this might make saving files a
+bit more time consuming.  By default, this feature is turned on, but
+you can turn it off by editing your project ``config.py`` file, though
+that is not recommended.
+
+
+Validating Object DB
+--------------------
+
+Since files on disk change over time project objectdb might hold
+invalid information.  Currently there is a basic incremental objectdb
+validation that can be used to remove or fix out of date information.
+Rope uses this feature by default but you can disable it by editing
+``config.py``.
+
+
+Custom Source Folders
+=====================
+
+By default rope searches the project for finding source folders
+(folders that should be searched for finding modules).  You can add
+paths to that list using ``source_folders`` project config.  Note that
+rope guesses project source folders correctly most of the time.  You
+can also extend python path using ``python_path`` config.
+
+
+Version Control Systems Support
+===============================
+
+When performing refactorings some files might need to be moved (when
+renaming a module) or new files might be created.  When using a VCS,
+rope detects and uses it to perform file system actions.
+
+Currently Mercurial_, GIT_, Darcs_ and SVN (using pysvn_ library) are
+supported.  They are selected based on dot files in project root
+directory.  For instance, Mercurial will be used if `mercurial` module
+is available and there is a ``.hg`` folder in project root.  Rope
+assumes either all files are under version control in a project or
+there is no version control at all.  Also don't forget to commit your
+changes yourself, rope doesn't do that.
+
+Adding support for other VCSs is easy; have a look at
+`library.txt`_.
+
+.. _pysvn: http://pysvn.tigris.org
+.. _Mercurial: http://selenic.com/mercurial
+.. _GIT: http://git.or.cz
+.. _darcs: http://darcs.net
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/docs/rope.txt	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,55 @@
+Features
+========
+
+Features implemented so far:
+
+* Refactorings
+
+  * Rename everything!
+  * Extract method/local variable
+  * Move class/function/module/package/method
+  * Inline method/local variable/parameter
+  * Restructuring (like converting ``${a}.f(${b})`` to
+    ``${b}.g(${a})`` where ``a: type=mymod.A``)
+  * Introduce factory
+  * Change method signature
+  * Transform module to package
+  * Encapsulate field
+  * Replace method with method object
+  * And a few others
+
+* Refactoring Features
+
+  * Extracting similar statements in extract refactorings
+  * Fixing imports when needed
+  * Previewing refactorings
+  * Undo/redo refactorings
+  * Stopping refactorings
+  * Cross-project refactorings
+  * Basic implicit interfaces handling in rename and change signature
+  * Mercurial_, GIT_, Darcs_ and SVN (pysvn_ library) support in
+    refactorings
+
+* IDE helpers
+
+  * Auto-completion
+  * Definition location
+  * Get pydoc
+  * Find occurrences
+  * Organize imports (remove unused and duplicate imports and sort them)
+  * Generating python elements
+
+* Object Inference
+
+  * Static and dynamic object analysis
+  * Handling built-in container types
+  * Saving object information on disk and validating them
+
+For more information see `overview.txt`_.
+
+
+.. _overview.txt: overview.html
+.. _pysvn: http://pysvn.tigris.org
+.. _Mercurial: http://selenic.com/mercurial
+.. _GIT: http://git.or.cz
+.. _darcs: http://darcs.net
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/__init__.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,17 @@
+"""rope, a python refactoring library"""
+
+INFO = __doc__
+VERSION = '0.9.3'
+COPYRIGHT = """\
+Copyright (C) 2006-2010 Ali Gholami Rudi
+Copyright (C) 2009-2010 Anton Gritsay
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of GNU General Public License as published by the
+Free Software Foundation; either version 2 of the license, or (at your
+opinion) 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."""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/__init__.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,8 @@
+"""Base rope package
+
+This package contains rope core modules that are used by other modules
+and packages.
+
+"""
+
+__all__ = ['project', 'libutils', 'exceptions']
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/arguments.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,109 @@
+import rope.base.evaluate
+from rope.base import ast
+
+
+class Arguments(object):
+    """A class for evaluating parameters passed to a function
+
+    You can use the `create_arguments` factory.  It handles implicit
+    first arguments.
+
+    """
+
+    def __init__(self, args, scope):
+        self.args = args
+        self.scope = scope
+        self.instance = None
+
+    def get_arguments(self, parameters):
+        result = []
+        for pyname in self.get_pynames(parameters):
+            if pyname is None:
+                result.append(None)
+            else:
+                result.append(pyname.get_object())
+        return result
+
+    def get_pynames(self, parameters):
+        result = [None] * max(len(parameters), len(self.args))
+        for index, arg in enumerate(self.args):
+            if isinstance(arg, ast.keyword) and arg.arg in parameters:
+                result[parameters.index(arg.arg)] = self._evaluate(arg.value)
+            else:
+                result[index] = self._evaluate(arg)
+        return result
+
+    def get_instance_pyname(self):
+        if self.args:
+            return self._evaluate(self.args[0])
+
+    def _evaluate(self, ast_node):
+        return rope.base.evaluate.eval_node(self.scope, ast_node)
+
+
+def create_arguments(primary, pyfunction, call_node, scope):
+    """A factory for creating `Arguments`"""
+    args = list(call_node.args)
+    args.extend(call_node.keywords)
+    called = call_node.func
+    # XXX: Handle constructors
+    if _is_method_call(primary, pyfunction) and \
+       isinstance(called, ast.Attribute):
+        args.insert(0, called.value)
+    return Arguments(args, scope)
+
+
+class ObjectArguments(object):
+
+    def __init__(self, pynames):
+        self.pynames = pynames
+
+    def get_arguments(self, parameters):
+        result = []
+        for pyname in self.pynames:
+            if pyname is None:
+                result.append(None)
+            else:
+                result.append(pyname.get_object())
+        return result
+
+    def get_pynames(self, parameters):
+        return self.pynames
+
+    def get_instance_pyname(self):
+        return self.pynames[0]
+class MixedArguments(object):
+
+    def __init__(self, pyname, arguments, scope):
+        """`argumens` is an instance of `Arguments`"""
+        self.pyname = pyname
+        self.args = arguments
+
+    def get_pynames(self, parameters):
+        return [self.pyname] + self.args.get_pynames(parameters[1:])
+
+    def get_arguments(self, parameters):
+        result = []
+        for pyname in self.get_pynames(parameters):
+            if pyname is None:
+                result.append(None)
+            else:
+                result.append(pyname.get_object())
+        return result
+
+    def get_instance_pyname(self):
+        return self.pyname
+
+
+def _is_method_call(primary, pyfunction):
+    if primary is None:
+        return False
+    pyobject = primary.get_object()
+    if isinstance(pyobject.get_type(), rope.base.pyobjects.PyClass) and \
+       isinstance(pyfunction, rope.base.pyobjects.PyFunction) and \
+       isinstance(pyfunction.parent, rope.base.pyobjects.PyClass):
+        return True
+    if isinstance(pyobject.get_type(), rope.base.pyobjects.AbstractClass) and \
+       isinstance(pyfunction, rope.base.builtins.BuiltinFunction):
+        return True
+    return False
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/ast.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,67 @@
+import _ast
+from _ast import *
+
+from rope.base import fscommands
+
+
+def parse(source, filename='<string>'):
+    # NOTE: the raw string should be given to `compile` function
+    if isinstance(source, unicode):
+        source = fscommands.unicode_to_file_data(source)
+    if '\r' in source:
+        source = source.replace('\r\n', '\n').replace('\r', '\n')
+    if not source.endswith('\n'):
+        source += '\n'
+    try:
+        return compile(source, filename, 'exec', _ast.PyCF_ONLY_AST)
+    except (TypeError, ValueError), e:
+        error = SyntaxError()
+        error.lineno = 1
+        error.filename = filename
+        error.msg = str(e)
+        raise error
+
+
+def walk(node, walker):
+    """Walk the syntax tree"""
+    method_name = '_' + node.__class__.__name__
+    method = getattr(walker, method_name, None)
+    if method is not None:
+        return method(node)
+    for child in get_child_nodes(node):
+        walk(child, walker)
+
+
+def get_child_nodes(node):
+    if isinstance(node, _ast.Module):
+        return node.body
+    result = []
+    if node._fields is not None:
+        for name in node._fields:
+            child = getattr(node, name)
+            if isinstance(child, list):
+                for entry in child:
+                    if isinstance(entry, _ast.AST):
+                        result.append(entry)
+            if isinstance(child, _ast.AST):
+                result.append(child)
+    return result
+
+
+def call_for_nodes(node, callback, recursive=False):
+    """If callback returns `True` the child nodes are skipped"""
+    result = callback(node)
+    if recursive and not result:
+        for child in get_child_nodes(node):
+            call_for_nodes(child, callback, recursive)
+
+
+def get_children(node):
+    result = []
+    if node._fields is not None:
+        for name in node._fields:
+            if name in ['lineno', 'col_offset']:
+                continue
+            child = getattr(node, name)
+            result.append(child)
+    return result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/astutils.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,61 @@
+from rope.base import ast
+
+
+def get_name_levels(node):
+    """Return a list of ``(name, level)`` tuples for assigned names
+
+    The `level` is `None` for simple assignments and is a list of
+    numbers for tuple assignments for example in::
+
+      a, (b, c) = x
+
+    The levels for for `a` is ``[0]``, for `b` is ``[1, 0]`` and for
+    `c` is ``[1, 1]``.
+
+    """
+    visitor = _NodeNameCollector()
+    ast.walk(node, visitor)
+    return visitor.names
+
+
+class _NodeNameCollector(object):
+
+    def __init__(self, levels=None):
+        self.names = []
+        self.levels = levels
+        self.index = 0
+
+    def _add_node(self, node):
+        new_levels = []
+        if self.levels is not None:
+            new_levels = list(self.levels)
+            new_levels.append(self.index)
+        self.index += 1
+        self._added(node, new_levels)
+
+    def _added(self, node, levels):
+        if hasattr(node, 'id'):
+            self.names.append((node.id, levels))
+
+    def _Name(self, node):
+        self._add_node(node)
+
+    def _Tuple(self, node):
+        new_levels = []
+        if self.levels is not None:
+            new_levels = list(self.levels)
+            new_levels.append(self.index)
+        self.index += 1
+        visitor = _NodeNameCollector(new_levels)
+        for child in ast.get_child_nodes(node):
+            ast.walk(child, visitor)
+        self.names.extend(visitor.names)
+
+    def _Subscript(self, node):
+        self._add_node(node)
+
+    def _Attribute(self, node):
+        self._add_node(node)
+
+    def _Slice(self, node):
+        self._add_node(node)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/builtins.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,762 @@
+"""This module trys to support builtin types and functions."""
+import inspect
+
+import rope.base.evaluate
+from rope.base import pynames, pyobjects, arguments, utils, ast
+
+
+class BuiltinModule(pyobjects.AbstractModule):
+
+    def __init__(self, name, pycore=None, initial={}):
+        super(BuiltinModule, self).__init__()
+        self.name = name
+        self.pycore = pycore
+        self.initial = initial
+
+    parent = None
+
+    def get_attributes(self):
+        return self.attributes
+
+    def get_doc(self):
+        if self.module:
+            return self.module.__doc__
+
+    def get_name(self):
+        return self.name.split('.')[-1]
+
+    @property
+    @utils.saveit
+    def attributes(self):
+        result = _object_attributes(self.module, self)
+        result.update(self.initial)
+        if self.pycore is not None:
+            submodules = self.pycore._builtin_submodules(self.name)
+            for name, module in submodules.iteritems():
+                result[name] = rope.base.builtins.BuiltinName(module)
+        return result
+
+    @property
+    @utils.saveit
+    def module(self):
+        try:
+            result = __import__(self.name)
+            for token in self.name.split('.')[1:]:
+                result = getattr(result, token, None)
+            return result
+        except ImportError:
+            return
+
+
+class _BuiltinElement(object):
+
+    def __init__(self, builtin, parent=None):
+        self.builtin = builtin
+        self._parent = parent
+
+    def get_doc(self):
+        if self.builtin:
+            return getattr(self.builtin, '__doc__', None)
+
+    def get_name(self):
+        if self.builtin:
+            return getattr(self.builtin, '__name__', None)
+
+    @property
+    def parent(self):
+        if self._parent is None:
+            return builtins
+        return self._parent
+
+
+class BuiltinClass(_BuiltinElement, pyobjects.AbstractClass):
+
+    def __init__(self, builtin, attributes, parent=None):
+        _BuiltinElement.__init__(self, builtin, parent)
+        pyobjects.AbstractClass.__init__(self)
+        self.initial = attributes
+
+    @utils.saveit
+    def get_attributes(self):
+        result = _object_attributes(self.builtin, self)
+        result.update(self.initial)
+        return result
+
+
+class BuiltinFunction(_BuiltinElement, pyobjects.AbstractFunction):
+
+    def __init__(self, returned=None, function=None, builtin=None,
+                 argnames=[], parent=None):
+        _BuiltinElement.__init__(self, builtin, parent)
+        pyobjects.AbstractFunction.__init__(self)
+        self.argnames = argnames
+        self.returned = returned
+        self.function = function
+
+    def get_returned_object(self, args):
+        if self.function is not None:
+            return self.function(_CallContext(self.argnames, args))
+        else:
+            return self.returned
+
+    def get_param_names(self, special_args=True):
+        return self.argnames
+
+
+class BuiltinUnknown(_BuiltinElement, pyobjects.PyObject):
+
+    def __init__(self, builtin):
+        super(BuiltinUnknown, self).__init__(pyobjects.get_unknown())
+        self.builtin = builtin
+        self.type = pyobjects.get_unknown()
+
+    def get_name(self):
+        return getattr(type(self.builtin), '__name__', None)
+
+    @utils.saveit
+    def get_attributes(self):
+        return _object_attributes(self.builtin, self)
+
+
+def _object_attributes(obj, parent):
+    attributes = {}
+    for name in dir(obj):
+        if name == 'None':
+            continue
+        child = getattr(obj, name)
+        pyobject = None
+        if inspect.isclass(child):
+            pyobject = BuiltinClass(child, {}, parent=parent)
+        elif inspect.isroutine(child):
+            pyobject = BuiltinFunction(builtin=child, parent=parent)
+        else:
+            pyobject = BuiltinUnknown(builtin=child)
+        attributes[name] = BuiltinName(pyobject)
+    return attributes
+
+
+def _create_builtin_type_getter(cls):
+    def _get_builtin(*args):
+        if not hasattr(cls, '_generated'):
+            cls._generated = {}
+        if args not in cls._generated:
+            cls._generated[args] = cls(*args)
+        return cls._generated[args]
+    return _get_builtin
+
+def _create_builtin_getter(cls):
+    type_getter = _create_builtin_type_getter(cls)
+    def _get_builtin(*args):
+        return pyobjects.PyObject(type_getter(*args))
+    return _get_builtin
+
+
+class _CallContext(object):
+
+    def __init__(self, argnames, args):
+        self.argnames = argnames
+        self.args = args
+
+    def _get_scope_and_pyname(self, pyname):
+        if pyname is not None and isinstance(pyname, pynames.AssignedName):
+            pymodule, lineno = pyname.get_definition_location()
+            if pymodule is None:
+                return None, None
+            if lineno is None:
+                lineno = 1
+            scope = pymodule.get_scope().get_inner_scope_for_line(lineno)
+            name = None
+            while name is None and scope is not None:
+                for current in scope.get_names():
+                    if scope[current] is pyname:
+                        name = current
+                        break
+                else:
+                    scope = scope.parent
+            return scope, name
+        return None, None
+
+    def get_argument(self, name):
+        if self.args:
+            args = self.args.get_arguments(self.argnames)
+            return args[self.argnames.index(name)]
+
+    def get_pyname(self, name):
+        if self.args:
+            args = self.args.get_pynames(self.argnames)
+            if name in self.argnames:
+                return args[self.argnames.index(name)]
+
+    def get_arguments(self, argnames):
+        if self.args:
+            return self.args.get_arguments(argnames)
+
+    def get_pynames(self, argnames):
+        if self.args:
+            return self.args.get_pynames(argnames)
+
+    def get_per_name(self):
+        if self.args is None:
+            return None
+        pyname = self.args.get_instance_pyname()
+        scope, name = self._get_scope_and_pyname(pyname)
+        if name is not None:
+            pymodule = pyname.get_definition_location()[0]
+            return pymodule.pycore.object_info.get_per_name(scope, name)
+        return None
+
+    def save_per_name(self, value):
+        if self.args is None:
+            return None
+        pyname = self.args.get_instance_pyname()
+        scope, name = self._get_scope_and_pyname(pyname)
+        if name is not None:
+            pymodule = pyname.get_definition_location()[0]
+            pymodule.pycore.object_info.save_per_name(scope, name, value)
+
+
+class _AttributeCollector(object):
+
+    def __init__(self, type):
+        self.attributes = {}
+        self.type = type
+
+    def __call__(self, name, returned=None, function=None,
+                 argnames=['self'], check_existence=True):
+        try:
+            builtin = getattr(self.type, name)
+        except AttributeError:
+            if check_existence:
+                raise
+            builtin=None
+        self.attributes[name] = BuiltinName(
+            BuiltinFunction(returned=returned, function=function,
+                            argnames=argnames, builtin=builtin))
+
+    def __setitem__(self, name, value):
+        self.attributes[name] = value
+
+
+class List(BuiltinClass):
+
+    def __init__(self, holding=None):
+        self.holding = holding
+        collector = _AttributeCollector(list)
+
+        collector('__iter__', function=self._iterator_get)
+        collector('__new__', function=self._new_list)
+
+        # Adding methods
+        collector('append', function=self._list_add, argnames=['self', 'value'])
+        collector('__setitem__', function=self._list_add,
+                  argnames=['self', 'index', 'value'])
+        collector('insert', function=self._list_add,
+                  argnames=['self', 'index', 'value'])
+        collector('extend', function=self._self_set,
+                  argnames=['self', 'iterable'])
+
+        # Getting methods
+        collector('__getitem__', function=self._list_get)
+        collector('pop', function=self._list_get)
+        collector('__getslice__', function=self._self_get)
+
+        super(List, self).__init__(list, collector.attributes)
+
+    def _new_list(self, args):
+        return _create_builtin(args, get_list)
+
+    def _list_add(self, context):
+        if self.holding is not None:
+            return
+        holding = context.get_argument('value')
+        if holding is not None and holding != pyobjects.get_unknown():
+            context.save_per_name(holding)
+
+    def _self_set(self, context):
+        if self.holding is not None:
+            return
+        iterable = context.get_pyname('iterable')
+        holding = _infer_sequence_for_pyname(iterable)
+        if holding is not None and holding != pyobjects.get_unknown():
+            context.save_per_name(holding)
+
+    def _list_get(self, context):
+        if self.holding is not None:
+            return self.holding
+        return context.get_per_name()
+
+    def _iterator_get(self, context):
+        return get_iterator(self._list_get(context))
+
+    def _self_get(self, context):
+        return get_list(self._list_get(context))
+
+
+get_list = _create_builtin_getter(List)
+get_list_type = _create_builtin_type_getter(List)
+
+
+class Dict(BuiltinClass):
+
+    def __init__(self, keys=None, values=None):
+        self.keys = keys
+        self.values = values
+        item = get_tuple(self.keys, self.values)
+        collector = _AttributeCollector(dict)
+        collector('__new__', function=self._new_dict)
+        collector('__setitem__', function=self._dict_add)
+        collector('popitem', function=self._item_get)
+        collector('pop', function=self._value_get)
+        collector('get', function=self._key_get)
+        collector('keys', function=self._key_list)
+        collector('values', function=self._value_list)
+        collector('items', function=self._item_list)
+        collector('copy', function=self._self_get)
+        collector('__getitem__', function=self._value_get)
+        collector('__iter__', function=self._key_iter)
+        collector('update', function=self._self_set)
+        super(Dict, self).__init__(dict, collector.attributes)
+
+    def _new_dict(self, args):
+        def do_create(holding=None):
+            if holding is None:
+                return get_dict()
+            type = holding.get_type()
+            if isinstance(type, Tuple) and len(type.get_holding_objects()) == 2:
+                return get_dict(*type.get_holding_objects())
+        return _create_builtin(args, do_create)
+
+    def _dict_add(self, context):
+        if self.keys is not None:
+            return
+        key, value = context.get_arguments(['self', 'key', 'value'])[1:]
+        if key is not None and key != pyobjects.get_unknown():
+            context.save_per_name(get_tuple(key, value))
+
+    def _item_get(self, context):
+        if self.keys is not None:
+            return get_tuple(self.keys, self.values)
+        item = context.get_per_name()
+        if item is None or not isinstance(item.get_type(), Tuple):
+            return get_tuple(self.keys, self.values)
+        return item
+
+    def _value_get(self, context):
+        item = self._item_get(context).get_type()
+        return item.get_holding_objects()[1]
+
+    def _key_get(self, context):
+        item = self._item_get(context).get_type()
+        return item.get_holding_objects()[0]
+
+    def _value_list(self, context):
+        return get_list(self._value_get(context))
+
+    def _key_list(self, context):
+        return get_list(self._key_get(context))
+
+    def _item_list(self, context):
+        return get_list(self._item_get(context))
+
+    def _value_iter(self, context):
+        return get_iterator(self._value_get(context))
+
+    def _key_iter(self, context):
+        return get_iterator(self._key_get(context))
+
+    def _item_iter(self, context):
+        return get_iterator(self._item_get(context))
+
+    def _self_get(self, context):
+        item = self._item_get(context).get_type()
+        key, value = item.get_holding_objects()[:2]
+        return get_dict(key, value)
+
+    def _self_set(self, context):
+        if self.keys is not None:
+            return
+        new_dict = context.get_pynames(['self', 'd'])[1]
+        if new_dict and isinstance(new_dict.get_object().get_type(), Dict):
+            args = arguments.ObjectArguments([new_dict])
+            items = new_dict.get_object()['popitem'].\
+                    get_object().get_returned_object(args)
+            context.save_per_name(items)
+        else:
+            holding = _infer_sequence_for_pyname(new_dict)
+            if holding is not None and isinstance(holding.get_type(), Tuple):
+                context.save_per_name(holding)
+
+
+get_dict = _create_builtin_getter(Dict)
+get_dict_type = _create_builtin_type_getter(Dict)
+
+
+class Tuple(BuiltinClass):
+
+    def __init__(self, *objects):
+        self.objects = objects
+        first = None
+        if objects:
+            first = objects[0]
+        attributes = {
+            '__getitem__': BuiltinName(BuiltinFunction(first)),
+            '__getslice__': BuiltinName(BuiltinFunction(pyobjects.PyObject(self))),
+            '__new__': BuiltinName(BuiltinFunction(function=self._new_tuple)),
+            '__iter__': BuiltinName(BuiltinFunction(get_iterator(first)))}
+        super(Tuple, self).__init__(tuple, attributes)
+
+    def get_holding_objects(self):
+        return self.objects
+
+    def _new_tuple(self, args):
+        return _create_builtin(args, get_tuple)
+
+
+get_tuple = _create_builtin_getter(Tuple)
+get_tuple_type = _create_builtin_type_getter(Tuple)
+
+
+class Set(BuiltinClass):
+
+    def __init__(self, holding=None):
+        self.holding = holding
+        collector = _AttributeCollector(set)
+        collector('__new__', function=self._new_set)
+
+        self_methods = ['copy', 'difference', 'intersection',
+                        'symmetric_difference', 'union']
+        for method in self_methods:
+            collector(method, function=self._self_get)
+        collector('add', function=self._set_add)
+        collector('update', function=self._self_set)
+        collector('update', function=self._self_set)
+        collector('symmetric_difference_update', function=self._self_set)
+        collector('difference_update', function=self._self_set)
+
+        collector('pop', function=self._set_get)
+        collector('__iter__', function=self._iterator_get)
+        super(Set, self).__init__(set, collector.attributes)
+
+    def _new_set(self, args):
+        return _create_builtin(args, get_set)
+
+    def _set_add(self, context):
+        if self.holding is not None:
+            return
+        holding = context.get_arguments(['self', 'value'])[1]
+        if holding is not None and holding != pyobjects.get_unknown():
+            context.save_per_name(holding)
+
+    def _self_set(self, context):
+        if self.holding is not None:
+            return
+        iterable = context.get_pyname('iterable')
+        holding = _infer_sequence_for_pyname(iterable)
+        if holding is not None and holding != pyobjects.get_unknown():
+            context.save_per_name(holding)
+
+    def _set_get(self, context):
+        if self.holding is not None:
+            return self.holding
+        return context.get_per_name()
+
+    def _iterator_get(self, context):
+        return get_iterator(self._set_get(context))
+
+    def _self_get(self, context):
+        return get_list(self._set_get(context))
+
+
+get_set = _create_builtin_getter(Set)
+get_set_type = _create_builtin_type_getter(Set)
+
+
+class Str(BuiltinClass):
+
+    def __init__(self):
+        self_object = pyobjects.PyObject(self)
+        collector = _AttributeCollector(str)
+        collector('__iter__', get_iterator(self_object), check_existence=False)
+
+        self_methods = ['__getitem__', '__getslice__', 'capitalize', 'center',
+                        'decode', 'encode', 'expandtabs', 'join', 'ljust',
+                        'lower', 'lstrip', 'replace', 'rjust', 'rstrip', 'strip',
+                        'swapcase', 'title', 'translate', 'upper', 'zfill']
+        for method in self_methods:
+            collector(method, self_object)
+
+        for method in ['rsplit', 'split', 'splitlines']:
+            collector(method, get_list(self_object))
+
+        super(Str, self).__init__(str, collector.attributes)
+
+    def get_doc(self):
+        return str.__doc__
+
+
+get_str = _create_builtin_getter(Str)
+get_str_type = _create_builtin_type_getter(Str)
+
+
+class BuiltinName(pynames.PyName):
+
+    def __init__(self, pyobject):
+        self.pyobject = pyobject
+
+    def get_object(self):
+        return self.pyobject
+
+    def get_definition_location(self):
+        return (None, None)
+
+class Iterator(pyobjects.AbstractClass):
+
+    def __init__(self, holding=None):
+        super(Iterator, self).__init__()
+        self.holding = holding
+        self.attributes = {
+            'next': BuiltinName(BuiltinFunction(self.holding)),
+            '__iter__': BuiltinName(BuiltinFunction(self))}
+
+    def get_attributes(self):
+        return self.attributes
+
+    def get_returned_object(self, args):
+        return self.holding
+
+get_iterator = _create_builtin_getter(Iterator)
+
+
+class Generator(pyobjects.AbstractClass):
+
+    def __init__(self, holding=None):
+        super(Generator, self).__init__()
+        self.holding = holding
+        self.attributes = {
+            'next': BuiltinName(BuiltinFunction(self.holding)),
+            '__iter__': BuiltinName(BuiltinFunction(get_iterator(self.holding))),
+            'close': BuiltinName(BuiltinFunction()),
+            'send': BuiltinName(BuiltinFunction()),
+            'throw': BuiltinName(BuiltinFunction())}
+
+    def get_attributes(self):
+        return self.attributes
+
+    def get_returned_object(self, args):
+        return self.holding
+
+get_generator = _create_builtin_getter(Generator)
+
+
+class File(BuiltinClass):
+
+    def __init__(self):
+        self_object = pyobjects.PyObject(self)
+        str_object = get_str()
+        str_list = get_list(get_str())
+        attributes = {}
+        def add(name, returned=None, function=None):
+            builtin = getattr(file, name, None)
+            attributes[name] = BuiltinName(
+                BuiltinFunction(returned=returned, function=function,
+                                builtin=builtin))
+        add('__iter__', get_iterator(str_object))
+        for method in ['next', 'read', 'readline', 'readlines']:
+            add(method, str_list)
+        for method in ['close', 'flush', 'lineno', 'isatty', 'seek', 'tell',
+                       'truncate', 'write', 'writelines']:
+            add(method)
+        super(File, self).__init__(file, attributes)
+
+
+get_file = _create_builtin_getter(File)
+get_file_type = _create_builtin_type_getter(File)
+
+
+class Property(BuiltinClass):
+
+    def __init__(self, fget=None, fset=None, fdel=None, fdoc=None):
+        self._fget = fget
+        self._fdoc = fdoc
+        attributes = {
+            'fget': BuiltinName(BuiltinFunction()),
+            'fset': BuiltinName(pynames.UnboundName()),
+            'fdel': BuiltinName(pynames.UnboundName()),
+            '__new__': BuiltinName(BuiltinFunction(function=_property_function))}
+        super(Property, self).__init__(property, attributes)
+
+    def get_property_object(self, args):
+        if isinstance(self._fget, pyobjects.AbstractFunction):
+            return self._fget.get_returned_object(args)
+
+
+def _property_function(args):
+    parameters = args.get_arguments(['fget', 'fset', 'fdel', 'fdoc'])
+    return pyobjects.PyObject(Property(parameters[0]))
+
+
+class Lambda(pyobjects.AbstractFunction):
+
+    def __init__(self, node, scope):
+        super(Lambda, self).__init__()
+        self.node = node
+        self.arguments = node.args
+        self.scope = scope
+
+    def get_returned_object(self, args):
+        result = rope.base.evaluate.eval_node(self.scope, self.node.body)
+        if result is not None:
+            return result.get_object()
+        else:
+            return pyobjects.get_unknown()
+
+    def get_module(self):
+        return self.parent.get_module()
+
+    def get_scope(self):
+        return self.scope
+
+    def get_kind(self):
+        return 'lambda'
+
+    def get_ast(self):
+        return self.node
+
+    def get_attributes(self):
+        return {}
+
+    def get_name(self):
+        return  'lambda'
+
+    def get_param_names(self, special_args=True):
+        result = [node.id for node in self.arguments.args
+                  if isinstance(node, ast.Name)]
+        if self.arguments.vararg:
+            result.append('*' + self.arguments.vararg)
+        if self.arguments.kwarg:
+            result.append('**' + self.arguments.kwarg)
+        return result
+
+    @property
+    def parent(self):
+        return self.scope.pyobject
+
+
+class BuiltinObject(BuiltinClass):
+
+    def __init__(self):
+        super(BuiltinObject, self).__init__(object, {})
+
+
+class BuiltinType(BuiltinClass):
+
+    def __init__(self):
+        super(BuiltinType, self).__init__(type, {})
+
+
+def _infer_sequence_for_pyname(pyname):
+    if pyname is None:
+        return None
+    seq = pyname.get_object()
+    args = arguments.ObjectArguments([pyname])
+    if '__iter__' in seq:
+        obj = seq['__iter__'].get_object()
+        if not isinstance(obj, pyobjects.AbstractFunction):
+            return None
+        iter = obj.get_returned_object(args)
+        if iter is not None and 'next' in iter:
+            holding = iter['next'].get_object().\
+                      get_returned_object(args)
+            return holding
+
+
+def _create_builtin(args, creator):
+    passed = args.get_pynames(['sequence'])[0]
+    if passed is None:
+        holding = None
+    else:
+        holding = _infer_sequence_for_pyname(passed)
+    if holding is not None:
+        return creator(holding)
+    else:
+        return creator()
+
+
+def _range_function(args):
+    return get_list()
+
+def _reversed_function(args):
+    return _create_builtin(args, get_iterator)
+
+def _sorted_function(args):
+    return _create_builtin(args, get_list)
+
+def _super_function(args):
+    passed_class, passed_self = args.get_arguments(['type', 'self'])
+    if passed_self is None:
+        return passed_class
+    else:
+        #pyclass = passed_self.get_type()
+        pyclass = passed_class
+        if isinstance(pyclass, pyobjects.AbstractClass):
+            supers = pyclass.get_superclasses()
+            if supers:
+                return pyobjects.PyObject(supers[0])
+        return passed_self
+
+def _zip_function(args):
+    args = args.get_pynames(['sequence'])
+    objects = []
+    for seq in args:
+        if seq is None:
+            holding = None
+        else:
+            holding = _infer_sequence_for_pyname(seq)
+        objects.append(holding)
+    tuple = get_tuple(*objects)
+    return get_list(tuple)
+
+def _enumerate_function(args):
+    passed = args.get_pynames(['sequence'])[0]
+    if passed is None:
+        holding = None
+    else:
+        holding = _infer_sequence_for_pyname(passed)
+    tuple = get_tuple(None, holding)
+    return get_iterator(tuple)
+
+def _iter_function(args):
+    passed = args.get_pynames(['sequence'])[0]
+    if passed is None:
+        holding = None
+    else:
+        holding = _infer_sequence_for_pyname(passed)
+    return get_iterator(holding)
+
+def _input_function(args):
+    return get_str()
+
+
+_initial_builtins = {
+    'list': BuiltinName(get_list_type()),
+    'dict': BuiltinName(get_dict_type()),
+    'tuple': BuiltinName(get_tuple_type()),
+    'set': BuiltinName(get_set_type()),
+    'str': BuiltinName(get_str_type()),
+    'file': BuiltinName(get_file_type()),
+    'open': BuiltinName(get_file_type()),
+    'unicode': BuiltinName(get_str_type()),
+    'range': BuiltinName(BuiltinFunction(function=_range_function, builtin=range)),
+    'reversed': BuiltinName(BuiltinFunction(function=_reversed_function, builtin=reversed)),
+    'sorted': BuiltinName(BuiltinFunction(function=_sorted_function, builtin=sorted)),
+    'super': BuiltinName(BuiltinFunction(function=_super_function, builtin=super)),
+    'property': BuiltinName(BuiltinFunction(function=_property_function, builtin=property)),
+    'zip': BuiltinName(BuiltinFunction(function=_zip_function, builtin=zip)),
+    'enumerate': BuiltinName(BuiltinFunction(function=_enumerate_function, builtin=enumerate)),
+    'object': BuiltinName(BuiltinObject()),
+    'type': BuiltinName(BuiltinType()),
+    'iter': BuiltinName(BuiltinFunction(function=_iter_function, builtin=iter)),
+    'raw_input': BuiltinName(BuiltinFunction(function=_input_function, builtin=raw_input)),
+    }
+
+builtins = BuiltinModule('__builtin__', initial=_initial_builtins)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/change.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,448 @@
+import datetime
+import difflib
+import os
+import time
+import warnings
+
+import rope.base.fscommands
+from rope.base import taskhandle, exceptions, utils
+
+
+class Change(object):
+    """The base class for changes
+
+    Rope refactorings return `Change` objects.  They can be previewed,
+    committed or undone.
+    """
+
+    def do(self, job_set=None):
+        """Perform the change
+        
+        .. note:: Do use this directly.  Use `Project.do()` instead.
+        """
+
+    def undo(self, job_set=None):
+        """Perform the change
+        
+        .. note:: Do use this directly.  Use `History.undo()` instead.
+        """
+
+    def get_description(self):
+        """Return the description of this change
+
+        This can be used for previewing the changes.
+        """
+        return str(self)
+
+    def get_changed_resources(self):
+        """Return the list of resources that will be changed"""
+        return []
+
+    @property
+    @utils.saveit
+    def _operations(self):
+        return _ResourceOperations(self.resource.project)
+
+
+class ChangeSet(Change):
+    """A collection of `Change` objects
+
+    This class holds a collection of changes.  This class provides
+    these fields:
+
+    * `changes`: the list of changes
+    * `description`: the goal of these changes
+    """
+
+    def __init__(self, description, timestamp=None):
+        self.changes = []
+        self.description = description
+        self.time = timestamp
+
+    def do(self, job_set=taskhandle.NullJobSet()):
+        try:
+            done = []
+            for change in self.changes:
+                change.do(job_set)
+                done.append(change)
+            self.time = time.time()
+        except Exception:
+            for change in done:
+                change.undo()
+            raise
+
+    def undo(self, job_set=taskhandle.NullJobSet()):
+        try:
+            done = []
+            for change in reversed(self.changes):
+                change.undo(job_set)
+                done.append(change)
+        except Exception:
+            for change in done:
+                change.do()
+            raise
+
+    def add_change(self, change):
+        self.changes.append(change)
+
+    def get_description(self):
+        result = [str(self) + ':\n\n\n']
+        for change in self.changes:
+            result.append(change.get_description())
+            result.append('\n')
+        return ''.join(result)
+
+    def __str__(self):
+        if self.time is not None:
+            date = datetime.datetime.fromtimestamp(self.time)
+            if date.date() == datetime.date.today():
+                string_date = 'today'
+            elif date.date() == (datetime.date.today() - datetime.timedelta(1)):
+                string_date = 'yesterday'
+            elif date.year == datetime.date.today().year:
+                string_date = date.strftime('%b %d')
+            else:
+                string_date = date.strftime('%d %b, %Y')
+            string_time = date.strftime('%H:%M:%S')
+            string_time = '%s %s ' % (string_date, string_time)
+            return self.description + ' - ' + string_time
+        return self.description
+
+    def get_changed_resources(self):
+        result = set()
+        for change in self.changes:
+            result.update(change.get_changed_resources())
+        return result
+
+
+def _handle_job_set(function):
+    """A decorator for handling `taskhandle.JobSet`\s
+
+    A decorator for handling `taskhandle.JobSet`\s for `do` and `undo`
+    methods of `Change`\s.
+    """
+    def call(self, job_set=taskhandle.NullJobSet()):
+        job_set.started_job(str(self))
+        function(self)
+        job_set.finished_job()
+    return call
+
+
+class ChangeContents(Change):
+    """A class to change the contents of a file
+
+    Fields:
+
+    * `resource`: The `rope.base.resources.File` to change
+    * `new_contents`: What to write in the file
+    """
+
+    def __init__(self, resource, new_contents, old_contents=None):
+        self.resource = resource
+        # IDEA: Only saving diffs; possible problems when undo/redoing
+        self.new_contents = new_contents
+        self.old_contents = old_contents
+
+    @_handle_job_set
+    def do(self):
+        if self.old_contents is None:
+            self.old_contents = self.resource.read()
+        self._operations.write_file(self.resource, self.new_contents)
+
+    @_handle_job_set
+    def undo(self):
+        if self.old_contents is None:
+            raise exceptions.HistoryError(
+                'Undoing a change that is not performed yet!')
+        self._operations.write_file(self.resource, self.old_contents)
+
+    def __str__(self):
+        return 'Change <%s>' % self.resource.path
+
+    def get_description(self):
+        new = self.new_contents
+        old = self.old_contents
+        if old is None:
+            if self.resource.exists():
+                old = self.resource.read()
+            else:
+                old = ''
+        result = difflib.unified_diff(
+            old.splitlines(True), new.splitlines(True),
+            'a/' + self.resource.path, 'b/' + self.resource.path)
+        return ''.join(list(result))
+
+    def get_changed_resources(self):
+        return [self.resource]
+
+
+class MoveResource(Change):
+    """Move a resource to a new location
+
+    Fields:
+
+    * `resource`: The `rope.base.resources.Resource` to move
+    * `new_resource`: The destination for move; It is the moved
+      resource not the folder containing that resource.
+    """
+
+    def __init__(self, resource, new_location, exact=False):
+        self.project = resource.project
+        self.resource = resource
+        if not exact:
+            new_location = _get_destination_for_move(resource, new_location)
+        if resource.is_folder():
+            self.new_resource = self.project.get_folder(new_location)
+        else:
+            self.new_resource = self.project.get_file(new_location)
+
+    @_handle_job_set
+    def do(self):
+        self._operations.move(self.resource, self.new_resource)
+
+    @_handle_job_set
+    def undo(self):
+        self._operations.move(self.new_resource, self.resource)
+
+    def __str__(self):
+        return 'Move <%s>' % self.resource.path
+
+    def get_description(self):
+        return 'rename from %s\nrename to %s' % (self.resource.path,
+                                                 self.new_resource.path)
+
+    def get_changed_resources(self):
+        return [self.resource, self.new_resource]
+
+
+class CreateResource(Change):
+    """A class to create a resource
+
+    Fields:
+
+    * `resource`: The resource to create
+    """
+
+    def __init__(self, resource):
+        self.resource = resource
+
+    @_handle_job_set
+    def do(self):
+        self._operations.create(self.resource)
+
+    @_handle_job_set
+    def undo(self):
+        self._operations.remove(self.resource)
+
+    def __str__(self):
+        return 'Create Resource <%s>' % (self.resource.path)
+
+    def get_description(self):
+        return 'new file %s' % (self.resource.path)
+
+    def get_changed_resources(self):
+        return [self.resource]
+
+    def _get_child_path(self, parent, name):
+        if parent.path == '':
+            return name
+        else:
+            return parent.path + '/' + name
+
+
+class CreateFolder(CreateResource):
+    """A class to create a folder
+
+    See docs for `CreateResource`.
+    """
+
+    def __init__(self, parent, name):
+        resource = parent.project.get_folder(self._get_child_path(parent, name))
+        super(CreateFolder, self).__init__(resource)
+
+
+class CreateFile(CreateResource):
+    """A class to create a file
+
+    See docs for `CreateResource`.
+    """
+
+    def __init__(self, parent, name):
+        resource = parent.project.get_file(self._get_child_path(parent, name))
+        super(CreateFile, self).__init__(resource)
+
+
+class RemoveResource(Change):
+    """A class to remove a resource
+
+    Fields:
+
+    * `resource`: The resource to be removed
+    """
+
+    def __init__(self, resource):
+        self.resource = resource
+
+    @_handle_job_set
+    def do(self):
+        self._operations.remove(self.resource)
+
+    # TODO: Undoing remove operations
+    @_handle_job_set
+    def undo(self):
+        raise NotImplementedError(
+            'Undoing `RemoveResource` is not implemented yet.')
+
+    def __str__(self):
+        return 'Remove <%s>' % (self.resource.path)
+
+    def get_changed_resources(self):
+        return [self.resource]
+
+
+def count_changes(change):
+    """Counts the number of basic changes a `Change` will make"""
+    if isinstance(change, ChangeSet):
+        result = 0
+        for child in change.changes:
+            result += count_changes(child)
+        return result
+    return 1
+
+def create_job_set(task_handle, change):
+    return task_handle.create_jobset(str(change), count_changes(change))
+
+
+class _ResourceOperations(object):
+
+    def __init__(self, project):
+        self.project = project
+        self.fscommands = project.fscommands
+        self.direct_commands = rope.base.fscommands.FileSystemCommands()
+
+    def _get_fscommands(self, resource):
+        if self.project.is_ignored(resource):
+            return self.direct_commands
+        return self.fscommands
+
+    def write_file(self, resource, contents):
+        data = rope.base.fscommands.unicode_to_file_data(contents)
+        fscommands = self._get_fscommands(resource)
+        fscommands.write(resource.real_path, data)
+        for observer in list(self.project.observers):
+            observer.resource_changed(resource)
+
+    def move(self, resource, new_resource):
+        fscommands = self._get_fscommands(resource)
+        fscommands.move(resource.real_path, new_resource.real_path)
+        for observer in list(self.project.observers):
+            observer.resource_moved(resource, new_resource)
+
+    def create(self, resource):
+        if resource.is_folder():
+            self._create_resource(resource.path, kind='folder')
+        else:
+            self._create_resource(resource.path)
+        for observer in list(self.project.observers):
+            observer.resource_created(resource)
+
+    def remove(self, resource):
+        fscommands = self._get_fscommands(resource)
+        fscommands.remove(resource.real_path)
+        for observer in list(self.project.observers):
+            observer.resource_removed(resource)
+
+    def _create_resource(self, file_name, kind='file'):
+        resource_path = self.project._get_resource_path(file_name)
+        if os.path.exists(resource_path):
+            raise exceptions.RopeError('Resource <%s> already exists'
+                                       % resource_path)
+        resource = self.project.get_file(file_name)
+        if not resource.parent.exists():
+            raise exceptions.ResourceNotFoundError(
+                'Parent folder of <%s> does not exist' % resource.path)
+        fscommands = self._get_fscommands(resource)
+        try:
+            if kind == 'file':
+                fscommands.create_file(resource_path)
+            else:
+                fscommands.create_folder(resource_path)
+        except IOError, e:
+            raise exceptions.RopeError(e)
+
+
+def _get_destination_for_move(resource, destination):
+    dest_path = resource.project._get_resource_path(destination)
+    if os.path.isdir(dest_path):
+        if destination != '':
+            return destination + '/' + resource.name
+        else:
+            return resource.name
+    return destination
+
+
+class ChangeToData(object):
+
+    def convertChangeSet(self, change):
+        description = change.description
+        changes = []
+        for child in change.changes:
+            changes.append(self(child))
+        return (description, changes, change.time)
+
+    def convertChangeContents(self, change):
+        return (change.resource.path, change.new_contents, change.old_contents)
+
+    def convertMoveResource(self, change):
+        return (change.resource.path, change.new_resource.path)
+
+    def convertCreateResource(self, change):
+        return (change.resource.path, change.resource.is_folder())
+
+    def convertRemoveResource(self, change):
+        return (change.resource.path, change.resource.is_folder())
+
+    def __call__(self, change):
+        change_type = type(change)
+        if change_type in (CreateFolder, CreateFile):
+            change_type = CreateResource
+        method = getattr(self, 'convert' + change_type.__name__)
+        return (change_type.__name__, method(change))
+
+
+class DataToChange(object):
+
+    def __init__(self, project):
+        self.project = project
+
+    def makeChangeSet(self, description, changes, time=None):
+        result = ChangeSet(description, time)
+        for child in changes:
+            result.add_change(self(child))
+        return result
+
+    def makeChangeContents(self, path, new_contents, old_contents):
+        resource = self.project.get_file(path)
+        return ChangeContents(resource, new_contents, old_contents)
+
+    def makeMoveResource(self, old_path, new_path):
+        resource = self.project.get_file(old_path)
+        return MoveResource(resource, new_path, exact=True)
+
+    def makeCreateResource(self, path, is_folder):
+        if is_folder:
+            resource = self.project.get_folder(path)
+        else:
+            resource = self.project.get_file(path)
+        return CreateResource(resource)
+
+    def makeRemoveResource(self, path, is_folder):
+        if is_folder:
+            resource = self.project.get_folder(path)
+        else:
+            resource = self.project.get_file(path)
+        return RemoveResource(resource)
+
+    def __call__(self, data):
+        method = getattr(self, 'make' + data[0])
+        return method(*data[1])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/codeanalyze.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,358 @@
+import bisect
+import re
+import token
+import tokenize
+
+
+class ChangeCollector(object):
+
+    def __init__(self, text):
+        self.text = text
+        self.changes = []
+
+    def add_change(self, start, end, new_text=None):
+        if new_text is None:
+            new_text = self.text[start:end]
+        self.changes.append((start, end, new_text))
+
+    def get_changed(self):
+        if not self.changes:
+            return None
+        def compare_changes(change1, change2):
+            return cmp(change1[:2], change2[:2])
+        self.changes.sort(compare_changes)
+        pieces = []
+        last_changed = 0
+        for change in self.changes:
+            start, end, text = change
+            pieces.append(self.text[last_changed:start] + text)
+            last_changed = end
+        if last_changed < len(self.text):
+            pieces.append(self.text[last_changed:])
+        result = ''.join(pieces)
+        if result != self.text:
+            return result
+
+
+class SourceLinesAdapter(object):
+    """Adapts source to Lines interface
+
+    Note: The creation of this class is expensive.
+    """
+
+    def __init__(self, source_code):
+        self.code = source_code
+        self.starts = None
+        self._initialize_line_starts()
+
+    def _initialize_line_starts(self):
+        self.starts = []
+        self.starts.append(0)
+        try:
+            i = 0
+            while True:
+                i = self.code.index('\n', i) + 1
+                self.starts.append(i)
+        except ValueError:
+            pass
+        self.starts.append(len(self.code) + 1)
+
+    def get_line(self, lineno):
+        return self.code[self.starts[lineno - 1]:
+                         self.starts[lineno] - 1]
+
+    def length(self):
+        return len(self.starts) - 1
+
+    def get_line_number(self, offset):
+        return bisect.bisect(self.starts, offset)
+
+    def get_line_start(self, lineno):
+        return self.starts[lineno - 1]
+
+    def get_line_end(self, lineno):
+        return self.starts[lineno] - 1
+
+
+class ArrayLinesAdapter(object):
+
+    def __init__(self, lines):
+        self.lines = lines
+
+    def get_line(self, line_number):
+        return self.lines[line_number - 1]
+
+    def length(self):
+        return len(self.lines)
+
+
+class LinesToReadline(object):
+
+    def __init__(self, lines, start):
+        self.lines = lines
+        self.current = start
+
+    def readline(self):
+        if self.current <= self.lines.length():
+            self.current += 1
+            return self.lines.get_line(self.current - 1) + '\n'
+        return ''
+
+    def __call__(self):
+        return self.readline()
+
+
+class _CustomGenerator(object):
+
+    def __init__(self, lines):
+        self.lines = lines
+        self.in_string = ''
+        self.open_count = 0
+        self.continuation = False
+
+    def __call__(self):
+        size = self.lines.length()
+        result = []
+        i = 1
+        while i <= size:
+            while i <= size and not self.lines.get_line(i).strip():
+                i += 1
+            if i <= size:
+                start = i
+                while True:
+                    line = self.lines.get_line(i)
+                    self._analyze_line(line)
+                    if not (self.continuation or self.open_count or
+                            self.in_string) or i == size:
+                        break
+                    i += 1
+                result.append((start, i))
+                i += 1
+        return result
+
+    _main_chars = re.compile(r'[\'|"|#|\\|\[|\]|\{|\}|\(|\)]')
+    def _analyze_line(self, line):
+        char = None
+        for match in self._main_chars.finditer(line):
+            char = match.group()
+            i = match.start()
+            if char in '\'"':
+                if not self.in_string:
+                    self.in_string = char
+                    if char * 3 == line[i:i + 3]:
+                        self.in_string = char * 3
+                elif self.in_string == line[i:i + len(self.in_string)] and \
+                     not (i > 0 and line[i - 1] == '\\' and
+                          not (i > 1 and line[i - 2] == '\\')):
+                    self.in_string = ''
+            if self.in_string:
+                continue
+            if char == '#':
+                break
+            if char in '([{':
+                self.open_count += 1
+            elif char in ')]}':
+                self.open_count -= 1
+        if line and char != '#' and line.endswith('\\'):
+            self.continuation = True
+        else:
+            self.continuation = False
+
+def custom_generator(lines):
+    return _CustomGenerator(lines)()
+
+
+class LogicalLineFinder(object):
+
+    def __init__(self, lines):
+        self.lines = lines
+
+    def logical_line_in(self, line_number):
+        indents = count_line_indents(self.lines.get_line(line_number))
+        tries = 0
+        while True:
+            block_start = get_block_start(self.lines, line_number, indents)
+            try:
+                return self._block_logical_line(block_start, line_number)
+            except IndentationError, e:
+                tries += 1
+                if tries == 5:
+                    raise e
+                lineno = e.lineno + block_start - 1
+                indents = count_line_indents(self.lines.get_line(lineno))
+
+    def generate_starts(self, start_line=1, end_line=None):
+        for start, end in self.generate_regions(start_line, end_line):
+            yield start
+
+    def generate_regions(self, start_line=1, end_line=None):
+        # XXX: `block_start` should be at a better position!
+        block_start = 1
+        readline = LinesToReadline(self.lines, block_start)
+        shifted = start_line - block_start + 1
+        try:
+            for start, end in self._logical_lines(readline):
+                real_start = start + block_start - 1
+                real_start = self._first_non_blank(real_start)
+                if end_line is not None and real_start >= end_line:
+                    break
+                real_end = end + block_start - 1
+                if real_start >= start_line:
+                    yield (real_start, real_end)
+        except tokenize.TokenError, e:
+            pass
+
+    def _block_logical_line(self, block_start, line_number):
+        readline = LinesToReadline(self.lines, block_start)
+        shifted = line_number - block_start + 1
+        region = self._calculate_logical(readline, shifted)
+        start = self._first_non_blank(region[0] + block_start - 1)
+        if region[1] is None:
+            end = self.lines.length()
+        else:
+            end = region[1] + block_start - 1
+        return start, end
+
+    def _calculate_logical(self, readline, line_number):
+        last_end = 1
+        try:
+            for start, end in self._logical_lines(readline):
+                if line_number <= end:
+                    return (start, end)
+                last_end = end + 1
+        except tokenize.TokenError, e:
+            current = e.args[1][0]
+            return (last_end, max(last_end, current - 1))
+        return (last_end, None)
+
+    def _logical_lines(self, readline):
+        last_end = 1
+        for current_token in tokenize.generate_tokens(readline):
+            current = current_token[2][0]
+            if current_token[0] == token.NEWLINE:
+                yield (last_end, current)
+                last_end = current + 1
+
+    def _first_non_blank(self, line_number):
+        current = line_number
+        while current < self.lines.length():
+            line = self.lines.get_line(current).strip()
+            if line and not line.startswith('#'):
+                return current
+            current += 1
+        return current
+
+
+def tokenizer_generator(lines):
+    return LogicalLineFinder(lines).generate_regions()
+
+
+class CachingLogicalLineFinder(object):
+
+    def __init__(self, lines, generate=custom_generator):
+        self.lines = lines
+        self._generate = generate
+
+    _starts = None
+    @property
+    def starts(self):
+        if self._starts is None:
+            self._init_logicals()
+        return self._starts
+
+    _ends = None
+    @property
+    def ends(self):
+        if self._ends is None:
+            self._init_logicals()
+        return self._ends
+
+    def _init_logicals(self):
+        """Should initialize _starts and _ends attributes"""
+        size = self.lines.length() + 1
+        self._starts = [None] * size
+        self._ends = [None] * size
+        for start, end in self._generate(self.lines):
+            self._starts[start] = True
+            self._ends[end] = True
+
+    def logical_line_in(self, line_number):
+        start = line_number
+        while start > 0 and not self.starts[start]:
+            start -= 1
+        if start == 0:
+            try:
+                start = self.starts.index(True, line_number)
+            except ValueError:
+                return (line_number, line_number)
+        return (start, self.ends.index(True, start))
+
+    def generate_starts(self, start_line=1, end_line=None):
+        if end_line is None:
+            end_line = self.lines.length()
+        for index in range(start_line, end_line):
+            if self.starts[index]:
+                yield index
+
+
+def get_block_start(lines, lineno, maximum_indents=80):
+    """Approximate block start"""
+    pattern = get_block_start_patterns()
+    for i in range(lineno, 0, -1):
+        match = pattern.search(lines.get_line(i))
+        if match is not None and \
+           count_line_indents(lines.get_line(i)) <= maximum_indents:
+            striped = match.string.lstrip()
+            # Maybe we're in a list comprehension or generator expression
+            if i > 1 and striped.startswith('if') or striped.startswith('for'):
+                bracs = 0
+                for j in range(i, min(i + 5, lines.length() + 1)):
+                    for c in lines.get_line(j):
+                        if c == '#':
+                            break
+                        if c in '[(':
+                            bracs += 1
+                        if c in ')]':
+                            bracs -= 1
+                            if bracs < 0:
+                                break
+                    if bracs < 0:
+                        break
+                if bracs < 0:
+                    continue
+            return i
+    return 1
+
+
+_block_start_pattern = None
+
+def get_block_start_patterns():
+    global _block_start_pattern
+    if not _block_start_pattern:
+        pattern = '^\\s*(((def|class|if|elif|except|for|while|with)\\s)|'\
+                  '((try|else|finally|except)\\s*:))'
+        _block_start_pattern = re.compile(pattern, re.M)
+    return _block_start_pattern
+
+
+def count_line_indents(line):
+    indents = 0
+    for char in line:
+        if char == ' ':
+            indents += 1
+        elif char == '\t':
+            indents += 8
+        else:
+            return indents
+    return 0
+
+
+def get_string_pattern():
+    start = r'(\b[uU]?[rR]?)?'
+    longstr = r'%s"""(\\.|"(?!"")|\\\n|[^"\\])*"""' % start
+    shortstr = r'%s"(\\.|[^"\\\n])*"' % start
+    return '|'.join([longstr, longstr.replace('"', "'"),
+                     shortstr, shortstr.replace('"', "'")])
+
+def get_comment_pattern():
+    return r'#[^\n]*'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/default_config.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,85 @@
+# The default ``config.py``
+
+
+def set_prefs(prefs):
+    """This function is called before opening the project"""
+
+    # Specify which files and folders to ignore in the project.
+    # Changes to ignored resources are not added to the history and
+    # VCSs.  Also they are not returned in `Project.get_files()`.
+    # Note that ``?`` and ``*`` match all characters but slashes.
+    # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
+    # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
+    # '.svn': matches 'pkg/.svn' and all of its children
+    # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
+    # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
+    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
+                                  '.hg', '.svn', '_svn', '.git']
+
+    # Specifies which files should be considered python files.  It is
+    # useful when you have scripts inside your project.  Only files
+    # ending with ``.py`` are considered to be python files by
+    # default.
+    #prefs['python_files'] = ['*.py']
+
+    # Custom source folders:  By default rope searches the project
+    # for finding source folders (folders that should be searched
+    # for finding modules).  You can add paths to that list.  Note
+    # that rope guesses project source folders correctly most of the
+    # time; use this if you have any problems.
+    # The folders should be relative to project root and use '/' for
+    # separating folders regardless of the platform rope is running on.
+    # 'src/my_source_folder' for instance.
+    #prefs.add('source_folders', 'src')
+
+    # You can extend python path for looking up modules
+    #prefs.add('python_path', '~/python/')
+
+    # Should rope save object information or not.
+    prefs['save_objectdb'] = True
+    prefs['compress_objectdb'] = False
+
+    # If `True`, rope analyzes each module when it is being saved.
+    prefs['automatic_soa'] = True
+    # The depth of calls to follow in static object analysis
+    prefs['soa_followed_calls'] = 0
+
+    # If `False` when running modules or unit tests "dynamic object
+    # analysis" is turned off.  This makes them much faster.
+    prefs['perform_doa'] = True
+
+    # Rope can check the validity of its object DB when running.
+    prefs['validate_objectdb'] = True
+
+    # How many undos to hold?
+    prefs['max_history_items'] = 32
+
+    # Shows whether to save history across sessions.
+    prefs['save_history'] = True
+    prefs['compress_history'] = False
+
+    # Set the number spaces used for indenting.  According to
+    # :PEP:`8`, it is best to use 4 spaces.  Since most of rope's
+    # unit-tests use 4 spaces it is more reliable, too.
+    prefs['indent_size'] = 4
+
+    # Builtin and c-extension modules that are allowed to be imported
+    # and inspected by rope.
+    prefs['extension_modules'] = []
+
+    # Add all standard c-extensions to extension_modules list.
+    prefs['import_dynload_stdmods'] = True
+
+    # If `True` modules with syntax errors are considered to be empty.
+    # The default value is `False`; When `False` syntax errors raise
+    # `rope.base.exceptions.ModuleSyntaxError` exception.
+    prefs['ignore_syntax_errors'] = False
+
+    # If `True`, rope ignores unresolvable imports.  Otherwise, they
+    # appear in the importing namespace.
+    prefs['ignore_bad_imports'] = False
+
+
+def project_opened(project):
+    """This function is called after opening the project"""
+    # Do whatever you like here!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/evaluate.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,321 @@
+import rope.base.builtins
+import rope.base.pynames
+import rope.base.pyobjects
+from rope.base import ast, astutils, exceptions, pyobjects, arguments, worder
+
+
+BadIdentifierError = exceptions.BadIdentifierError
+
+def eval_location(pymodule, offset):
+    """Find the pyname at the offset"""
+    return eval_location2(pymodule, offset)[1]
+
+
+def eval_location2(pymodule, offset):
+    """Find the primary and pyname at offset"""
+    pyname_finder = ScopeNameFinder(pymodule)
+    return pyname_finder.get_primary_and_pyname_at(offset)
+
+
+def eval_node(scope, node):
+    """Evaluate a `ast.AST` node and return a PyName
+
+    Return `None` if the expression cannot be evaluated.
+    """
+    return eval_node2(scope, node)[1]
+
+
+def eval_node2(scope, node):
+    evaluator = StatementEvaluator(scope)
+    ast.walk(node, evaluator)
+    return evaluator.old_result, evaluator.result
+
+
+def eval_str(holding_scope, name):
+    return eval_str2(holding_scope, name)[1]
+
+
+def eval_str2(holding_scope, name):
+    try:
+        # parenthesizing for handling cases like 'a_var.\nattr'
+        node = ast.parse('(%s)' % name)
+    except SyntaxError:
+        raise BadIdentifierError('Not a resolvable python identifier selected.')
+    return eval_node2(holding_scope, node)
+
+
+class ScopeNameFinder(object):
+
+    def __init__(self, pymodule):
+        self.module_scope = pymodule.get_scope()
+        self.lines = pymodule.lines
+        self.worder = worder.Worder(pymodule.source_code, True)
+
+    def _is_defined_in_class_body(self, holding_scope, offset, lineno):
+        if lineno == holding_scope.get_start() and \
+           holding_scope.parent is not None and \
+           holding_scope.parent.get_kind() == 'Class' and \
+           self.worder.is_a_class_or_function_name_in_header(offset):
+            return True
+        if lineno != holding_scope.get_start() and \
+           holding_scope.get_kind() == 'Class' and \
+           self.worder.is_name_assigned_in_class_body(offset):
+            return True
+        return False
+
+    def _is_function_name_in_function_header(self, scope, offset, lineno):
+        if scope.get_start() <= lineno <= scope.get_body_start() and \
+           scope.get_kind() == 'Function' and \
+           self.worder.is_a_class_or_function_name_in_header(offset):
+            return True
+        return False
+
+    def get_pyname_at(self, offset):
+        return self.get_primary_and_pyname_at(offset)[1]
+
+    def get_primary_and_pyname_at(self, offset):
+        lineno = self.lines.get_line_number(offset)
+        holding_scope = self.module_scope.get_inner_scope_for_line(lineno)
+        # function keyword parameter
+        if self.worder.is_function_keyword_parameter(offset):
+            keyword_name = self.worder.get_word_at(offset)
+            pyobject = self.get_enclosing_function(offset)
+            if isinstance(pyobject, pyobjects.PyFunction):
+                return (None, pyobject.get_parameters().get(keyword_name, None))
+        # class body
+        if self._is_defined_in_class_body(holding_scope, offset, lineno):
+            class_scope = holding_scope
+            if lineno == holding_scope.get_start():
+                class_scope = holding_scope.parent
+            name = self.worder.get_primary_at(offset).strip()
+            try:
+                return (None, class_scope.pyobject[name])
+            except rope.base.exceptions.AttributeNotFoundError:
+                return (None, None)
+        # function header
+        if self._is_function_name_in_function_header(holding_scope, offset, lineno):
+            name = self.worder.get_primary_at(offset).strip()
+            return (None, holding_scope.parent[name])
+        # from statement module
+        if self.worder.is_from_statement_module(offset):
+            module = self.worder.get_primary_at(offset)
+            module_pyname = self._find_module(module)
+            return (None, module_pyname)
+        if self.worder.is_from_aliased(offset):
+            name = self.worder.get_from_aliased(offset)
+        else:
+            name = self.worder.get_primary_at(offset)
+        return eval_str2(holding_scope, name)
+
+    def get_enclosing_function(self, offset):
+        function_parens = self.worder.find_parens_start_from_inside(offset)
+        try:
+            function_pyname = self.get_pyname_at(function_parens - 1)
+        except BadIdentifierError:
+            function_pyname = None
+        if function_pyname is not None:
+            pyobject = function_pyname.get_object()
+            if isinstance(pyobject, pyobjects.AbstractFunction):
+                return pyobject
+            elif isinstance(pyobject, pyobjects.AbstractClass) and \
+                 '__init__' in pyobject:
+                return pyobject['__init__'].get_object()
+            elif '__call__' in pyobject:
+                return pyobject['__call__'].get_object()
+        return None
+
+    def _find_module(self, module_name):
+        dots = 0
+        while module_name[dots] == '.':
+            dots += 1
+        return rope.base.pynames.ImportedModule(
+            self.module_scope.pyobject, module_name[dots:], dots)
+
+
+class StatementEvaluator(object):
+
+    def __init__(self, scope):
+        self.scope = scope
+        self.result = None
+        self.old_result = None
+
+    def _Name(self, node):
+        self.result = self.scope.lookup(node.id)
+
+    def _Attribute(self, node):
+        pyname = eval_node(self.scope, node.value)
+        if pyname is None:
+            pyname = rope.base.pynames.UnboundName()
+        self.old_result = pyname
+        if pyname.get_object() != rope.base.pyobjects.get_unknown():
+            try:
+                self.result = pyname.get_object()[node.attr]
+            except exceptions.AttributeNotFoundError:
+                self.result = None
+
+    def _Call(self, node):
+        primary, pyobject = self._get_primary_and_object_for_node(node.func)
+        if pyobject is None:
+            return
+        def _get_returned(pyobject):
+            args = arguments.create_arguments(primary, pyobject,
+                                              node, self.scope)
+            return pyobject.get_returned_object(args)
+        if isinstance(pyobject, rope.base.pyobjects.AbstractClass):
+            result = None
+            if '__new__' in pyobject:
+                new_function = pyobject['__new__'].get_object()
+                result = _get_returned(new_function)
+            if result is None or \
+               result == rope.base.pyobjects.get_unknown():
+                result = rope.base.pyobjects.PyObject(pyobject)
+            self.result = rope.base.pynames.UnboundName(pyobject=result)
+            return
+
+        pyfunction = None
+        if isinstance(pyobject, rope.base.pyobjects.AbstractFunction):
+            pyfunction = pyobject
+        elif '__call__' in pyobject:
+            pyfunction = pyobject['__call__'].get_object()
+        if pyfunction is not None:
+            self.result = rope.base.pynames.UnboundName(
+                pyobject=_get_returned(pyfunction))
+
+    def _Str(self, node):
+        self.result = rope.base.pynames.UnboundName(
+            pyobject=rope.base.builtins.get_str())
+
+    def _Num(self, node):
+        type_name = type(node.n).__name__
+        self.result = self._get_builtin_name(type_name)
+
+    def _get_builtin_name(self, type_name):
+        pytype = rope.base.builtins.builtins[type_name].get_object()
+        return rope.base.pynames.UnboundName(
+            rope.base.pyobjects.PyObject(pytype))
+
+    def _BinOp(self, node):
+        self.result = rope.base.pynames.UnboundName(
+            self._get_object_for_node(node.left))
+
+    def _BoolOp(self, node):
+        pyobject = self._get_object_for_node(node.values[0])
+        if pyobject is None:
+            pyobject = self._get_object_for_node(node.values[1])
+        self.result = rope.base.pynames.UnboundName(pyobject)
+
+    def _Repr(self, node):
+        self.result = self._get_builtin_name('str')
+
+    def _UnaryOp(self, node):
+        self.result = rope.base.pynames.UnboundName(
+            self._get_object_for_node(node.operand))
+
+    def _Compare(self, node):
+        self.result = self._get_builtin_name('bool')
+
+    def _Dict(self, node):
+        keys = None
+        values = None
+        if node.keys:
+            keys = self._get_object_for_node(node.keys[0])
+            values = self._get_object_for_node(node.values[0])
+        self.result = rope.base.pynames.UnboundName(
+            pyobject=rope.base.builtins.get_dict(keys, values))
+
+    def _List(self, node):
+        holding = None
+        if node.elts:
+            holding = self._get_object_for_node(node.elts[0])
+        self.result = rope.base.pynames.UnboundName(
+            pyobject=rope.base.builtins.get_list(holding))
+
+    def _ListComp(self, node):
+        pyobject = self._what_does_comprehension_hold(node)
+        self.result = rope.base.pynames.UnboundName(
+            pyobject=rope.base.builtins.get_list(pyobject))
+
+    def _GeneratorExp(self, node):
+        pyobject = self._what_does_comprehension_hold(node)
+        self.result = rope.base.pynames.UnboundName(
+            pyobject=rope.base.builtins.get_iterator(pyobject))
+
+    def _what_does_comprehension_hold(self, node):
+        scope = self._make_comprehension_scope(node)
+        pyname = eval_node(scope, node.elt)
+        return pyname.get_object() if pyname is not None else None
+
+    def _make_comprehension_scope(self, node):
+        scope = self.scope
+        module = scope.pyobject.get_module()
+        names = {}
+        for comp in node.generators:
+            new_names = _get_evaluated_names(comp.target, comp.iter, module,
+                                             '.__iter__().next()', node.lineno)
+            names.update(new_names)
+        return rope.base.pyscopes.TemporaryScope(scope.pycore, scope, names)
+
+    def _Tuple(self, node):
+        objects = []
+        if len(node.elts) < 4:
+            for stmt in node.elts:
+                pyobject = self._get_object_for_node(stmt)
+                objects.append(pyobject)
+        else:
+            objects.append(self._get_object_for_node(node.elts[0]))
+        self.result = rope.base.pynames.UnboundName(
+            pyobject=rope.base.builtins.get_tuple(*objects))
+
+    def _get_object_for_node(self, stmt):
+        pyname = eval_node(self.scope, stmt)
+        pyobject = None
+        if pyname is not None:
+            pyobject = pyname.get_object()
+        return pyobject
+
+    def _get_primary_and_object_for_node(self, stmt):
+        primary, pyname = eval_node2(self.scope, stmt)
+        pyobject = None
+        if pyname is not None:
+            pyobject = pyname.get_object()
+        return primary, pyobject
+
+    def _Subscript(self, node):
+        if isinstance(node.slice, ast.Index):
+            self._call_function(node.value, '__getitem__',
+                                [node.slice.value])
+        elif isinstance(node.slice, ast.Slice):
+            self._call_function(node.value, '__getslice__')
+
+    def _call_function(self, node, function_name, other_args=None):
+        pyname = eval_node(self.scope, node)
+        if pyname is not None:
+            pyobject = pyname.get_object()
+        else:
+            return
+        if function_name in pyobject:
+            called = pyobject[function_name].get_object()
+            if not called or not isinstance(called, pyobjects.AbstractFunction):
+                return
+            args = [node]
+            if other_args:
+                args += other_args
+            arguments_ = arguments.Arguments(args, self.scope)
+            self.result = rope.base.pynames.UnboundName(
+                pyobject=called.get_returned_object(arguments_))
+
+    def _Lambda(self, node):
+        self.result = rope.base.pynames.UnboundName(
+            pyobject=rope.base.builtins.Lambda(node, self.scope))
+
+
+def _get_evaluated_names(targets, assigned, module, evaluation, lineno):
+    result = {}
+    for name, levels in astutils.get_name_levels(targets):
+        assignment = rope.base.pynames.AssignmentValue(assigned, levels,
+                                                       evaluation)
+        # XXX: this module should not access `rope.base.pynamesdef`!
+        pyname = rope.base.pynamesdef.AssignedName(lineno, module)
+        pyname.assignments.append(assignment)
+        result[name] = pyname
+    return result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/exceptions.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,61 @@
+class RopeError(Exception):
+    """Base exception for rope"""
+
+
+class ResourceNotFoundError(RopeError):
+    """Resource not found exception"""
+
+
+class RefactoringError(RopeError):
+    """Errors for performing a refactoring"""
+
+
+class InterruptedTaskError(RopeError):
+    """The task has been interrupted"""
+
+
+class HistoryError(RopeError):
+    """Errors for history undo/redo operations"""
+
+
+class ModuleNotFoundError(RopeError):
+    """Module not found exception"""
+
+
+class AttributeNotFoundError(RopeError):
+    """Attribute not found exception"""
+
+
+class NameNotFoundError(RopeError):
+    """Name not found exception"""
+
+
+class BadIdentifierError(RopeError):
+    """The name cannot be resolved"""
+
+
+class ModuleSyntaxError(RopeError):
+    """Module has syntax errors
+
+    The `filename` and `lineno` fields indicate where the error has
+    occurred.
+
+    """
+
+    def __init__(self, filename, lineno, message):
+        self.filename = filename
+        self.lineno = lineno
+        self.message_ = message
+        super(ModuleSyntaxError, self).__init__(
+            'Syntax error in file <%s> line <%s>: %s' %
+            (filename, lineno, message))
+
+
+class ModuleDecodeError(RopeError):
+    """Cannot decode module"""
+
+    def __init__(self, filename, message):
+        self.filename = filename
+        self.message_ = message
+        super(ModuleDecodeError, self).__init__(
+            'Cannot decode file <%s>: %s' % (filename, message))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/fscommands.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,268 @@
+"""Project file system commands.
+
+This modules implements file system operations used by rope.  Different
+version control systems can be supported by implementing the interface
+provided by `FileSystemCommands` class.  See `SubversionCommands` and
+`MercurialCommands` for example.
+
+"""
+import os
+import shutil
+import subprocess
+
+
+def create_fscommands(root):
+    dirlist = os.listdir(root)
+    commands = {'.hg': MercurialCommands,
+                '.svn': SubversionCommands,
+                '.git': GITCommands,
+                '_svn': SubversionCommands,
+                '_darcs': DarcsCommands}
+    for key in commands:
+        if key in dirlist:
+            try:
+                return commands[key](root)
+            except (ImportError, OSError):
+                pass
+    return FileSystemCommands()
+
+
+class FileSystemCommands(object):
+
+    def create_file(self, path):
+        open(path, 'w').close()
+
+    def create_folder(self, path):
+        os.mkdir(path)
+
+    def move(self, path, new_location):
+        shutil.move(path, new_location)
+
+    def remove(self, path):
+        if os.path.isfile(path):
+            os.remove(path)
+        else:
+            shutil.rmtree(path)
+
+    def write(self, path, data):
+        file_ = open(path, 'wb')
+        try:
+            file_.write(data)
+        finally:
+            file_.close()
+
+
+class SubversionCommands(object):
+
+    def __init__(self, *args):
+        self.normal_actions = FileSystemCommands()
+        import pysvn
+        self.client = pysvn.Client()
+
+    def create_file(self, path):
+        self.normal_actions.create_file(path)
+        self.client.add(path, force=True)
+
+    def create_folder(self, path):
+        self.normal_actions.create_folder(path)
+        self.client.add(path, force=True)
+
+    def move(self, path, new_location):
+        self.client.move(path, new_location, force=True)
+
+    def remove(self, path):
+        self.client.remove(path, force=True)
+
+    def write(self, path, data):
+        self.normal_actions.write(path, data)
+
+
+class MercurialCommands(object):
+
+    def __init__(self, root):
+        self.hg = self._import_mercurial()
+        self.normal_actions = FileSystemCommands()
+        try:
+            self.ui = self.hg.ui.ui(
+                verbose=False, debug=False, quiet=True,
+                interactive=False, traceback=False, report_untrusted=False)
+        except:
+            self.ui = self.hg.ui.ui()
+            self.ui.setconfig('ui', 'interactive', 'no')
+            self.ui.setconfig('ui', 'debug', 'no')
+            self.ui.setconfig('ui', 'traceback', 'no')
+            self.ui.setconfig('ui', 'verbose', 'no')
+            self.ui.setconfig('ui', 'report_untrusted', 'no')
+            self.ui.setconfig('ui', 'quiet', 'yes')
+            self.ui.setconfig('extensions', 'progress', '!')
+
+        self.repo = self.hg.hg.repository(self.ui, root)
+
+    def _import_mercurial(self):
+        import mercurial.commands
+        import mercurial.hg
+        import mercurial.ui
+        return mercurial
+
+    def create_file(self, path):
+        self.normal_actions.create_file(path)
+        self.hg.commands.add(self.ui, self.repo, path)
+
+    def create_folder(self, path):
+        self.normal_actions.create_folder(path)
+
+    def move(self, path, new_location):
+        self.hg.commands.rename(self.ui, self.repo, path,
+                                new_location, after=False)
+
+    def remove(self, path):
+        self.hg.commands.remove(self.ui, self.repo, path)
+
+    def write(self, path, data):
+        self.normal_actions.write(path, data)
+
+
+class GITCommands(object):
+
+    def __init__(self, root):
+        self.root = root
+        self._do(['version'])
+        self.normal_actions = FileSystemCommands()
+
+    def create_file(self, path):
+        self.normal_actions.create_file(path)
+        self._do(['add', self._in_dir(path)])
+
+    def create_folder(self, path):
+        self.normal_actions.create_folder(path)
+
+    def move(self, path, new_location):
+        self._do(['mv', self._in_dir(path), self._in_dir(new_location)])
+
+    def remove(self, path):
+        self._do(['rm', self._in_dir(path)])
+
+    def write(self, path, data):
+        # XXX: should we use ``git add``?
+        self.normal_actions.write(path, data)
+
+    def _do(self, args):
+        _execute(['git'] + args, cwd=self.root)
+
+    def _in_dir(self, path):
+        if path.startswith(self.root):
+            return path[len(self.root) + 1:]
+        return self.root
+
+
+class DarcsCommands(object):
+
+    def __init__(self, root):
+        self.root = root
+        self.normal_actions = FileSystemCommands()
+
+    def create_file(self, path):
+        self.normal_actions.create_file(path)
+        self._do(['add', path])
+
+    def create_folder(self, path):
+        self.normal_actions.create_folder(path)
+        self._do(['add', path])
+
+    def move(self, path, new_location):
+        self._do(['mv', path, new_location])
+
+    def remove(self, path):
+        self.normal_actions.remove(path)
+
+    def write(self, path, data):
+        self.normal_actions.write(path, data)
+
+    def _do(self, args):
+        _execute(['darcs'] + args, cwd=self.root)
+
+
+def _execute(args, cwd=None):
+    process = subprocess.Popen(args, cwd=cwd, stdout=subprocess.PIPE)
+    process.wait()
+    return process.returncode
+
+
+def unicode_to_file_data(contents, encoding=None):
+    if not isinstance(contents, unicode):
+        return contents
+    if encoding is None:
+        encoding = read_str_coding(contents)
+    if encoding is not None:
+        return contents.encode(encoding)
+    try:
+        return contents.encode()
+    except UnicodeEncodeError:
+        return contents.encode('utf-8')
+
+def file_data_to_unicode(data, encoding=None):
+    result = _decode_data(data, encoding)
+    if '\r' in result:
+        result = result.replace('\r\n', '\n').replace('\r', '\n')
+    return result
+
+def _decode_data(data, encoding):
+    if isinstance(data, unicode):
+        return data
+    if encoding is None:
+        encoding = read_str_coding(data)
+    if encoding is None:
+        # there is no encoding tip, we need to guess.
+        # PEP263 says that "encoding not explicitly defined" means it is ascii,
+        # but we will use utf8 instead since utf8 fully covers ascii and btw is
+        # the only non-latin sane encoding.
+        encoding = 'utf-8'
+    try:
+        return data.decode(encoding)
+    except (UnicodeError, LookupError):
+        # fallback to latin1: it should never fail
+        return data.decode('latin1')
+
+
+def read_file_coding(path):
+    file = open(path, 'b')
+    count = 0
+    result = []
+    buffsize = 10
+    while True:
+        current = file.read(10)
+        if not current:
+            break
+        count += current.count('\n')
+        result.append(current)
+    file.close()
+    return _find_coding(''.join(result))
+
+
+def read_str_coding(source):
+    try:
+        first = source.index('\n') + 1
+        second = source.index('\n', first) + 1
+    except ValueError:
+        second = len(source)
+    return _find_coding(source[:second])
+
+
+def _find_coding(text):
+    coding = 'coding'
+    try:
+        start = text.index(coding) + len(coding)
+        if text[start] not in '=:':
+            return
+        start += 1
+        while start < len(text) and text[start].isspace():
+            start += 1
+        end = start
+        while end < len(text):
+            c = text[end]
+            if not c.isalnum() and c not in '-_':
+                break
+            end += 1
+        return text[start:end]
+    except ValueError:
+        pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/history.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,235 @@
+from rope.base import exceptions, change, taskhandle
+
+
+class History(object):
+    """A class that holds project history"""
+
+    def __init__(self, project, maxundos=None):
+        self.project = project
+        self._undo_list = []
+        self._redo_list = []
+        self._maxundos = maxundos
+        self._load_history()
+        self.project.data_files.add_write_hook(self.write)
+        self.current_change = None
+
+    def _load_history(self):
+        if self.save:
+            result = self.project.data_files.read_data(
+                'history', compress=self.compress, import_=True)
+            if result is not None:
+                to_change = change.DataToChange(self.project)
+                for data in result[0]:
+                    self._undo_list.append(to_change(data))
+                for data in result[1]:
+                    self._redo_list.append(to_change(data))
+
+    def do(self, changes, task_handle=taskhandle.NullTaskHandle()):
+        """Perform the change and add it to the `self.undo_list`
+
+        Note that uninteresting changes (changes to ignored files)
+        will not be appended to `self.undo_list`.
+
+        """
+        try:
+            self.current_change = changes
+            changes.do(change.create_job_set(task_handle, changes))
+        finally:
+            self.current_change = None
+        if self._is_change_interesting(changes):
+            self.undo_list.append(changes)
+            self._remove_extra_items()
+        del self.redo_list[:]
+
+    def _remove_extra_items(self):
+        if len(self.undo_list) > self.max_undos:
+            del self.undo_list[0:len(self.undo_list) - self.max_undos]
+
+    def _is_change_interesting(self, changes):
+        for resource in changes.get_changed_resources():
+            if not self.project.is_ignored(resource):
+                return True
+        return False
+
+    def undo(self, change=None, drop=False,
+             task_handle=taskhandle.NullTaskHandle()):
+        """Redo done changes from the history
+
+        When `change` is `None`, the last done change will be undone.
+        If change is not `None` it should be an item from
+        `self.undo_list`; this change and all changes that depend on
+        it will be undone.  In both cases the list of undone changes
+        will be returned.
+
+        If `drop` is `True`, the undone change will not be appended to
+        the redo list.
+
+        """
+        if not self._undo_list:
+            raise exceptions.HistoryError('Undo list is empty')
+        if change is None:
+            change = self.undo_list[-1]
+        dependencies = self._find_dependencies(self.undo_list, change)
+        self._move_front(self.undo_list, dependencies)
+        self._perform_undos(len(dependencies), task_handle)
+        result = self.redo_list[-len(dependencies):]
+        if drop:
+            del self.redo_list[-len(dependencies):]
+        return result
+
+    def redo(self, change=None, task_handle=taskhandle.NullTaskHandle()):
+        """Redo undone changes from the history
+
+        When `change` is `None`, the last undone change will be
+        redone.  If change is not `None` it should be an item from
+        `self.redo_list`; this change and all changes that depend on
+        it will be redone.  In both cases the list of redone changes
+        will be returned.
+
+        """
+        if not self.redo_list:
+            raise exceptions.HistoryError('Redo list is empty')
+        if change is None:
+            change = self.redo_list[-1]
+        dependencies = self._find_dependencies(self.redo_list, change)
+        self._move_front(self.redo_list, dependencies)
+        self._perform_redos(len(dependencies), task_handle)
+        return self.undo_list[-len(dependencies):]
+
+    def _move_front(self, change_list, changes):
+        for change in changes:
+            change_list.remove(change)
+            change_list.append(change)
+
+    def _find_dependencies(self, change_list, change):
+        index = change_list.index(change)
+        return _FindChangeDependencies(change_list[index:])()
+
+    def _perform_undos(self, count, task_handle):
+        for i in range(count):
+            self.current_change = self.undo_list[-1]
+            try:
+                job_set = change.create_job_set(task_handle,
+                                                self.current_change)
+                self.current_change.undo(job_set)
+            finally:
+                self.current_change = None
+            self.redo_list.append(self.undo_list.pop())
+
+    def _perform_redos(self, count, task_handle):
+        for i in range(count):
+            self.current_change = self.redo_list[-1]
+            try:
+                job_set = change.create_job_set(task_handle,
+                                                self.current_change)
+                self.current_change.do(job_set)
+            finally:
+                self.current_change = None
+            self.undo_list.append(self.redo_list.pop())
+
+    def contents_before_current_change(self, file):
+        if self.current_change is None:
+            return None
+        result = self._search_for_change_contents([self.current_change], file)
+        if result is not None:
+            return result
+        if file.exists() and not file.is_folder():
+            return file.read()
+        else:
+            return None
+
+    def _search_for_change_contents(self, change_list, file):
+        for change_ in reversed(change_list):
+            if isinstance(change_, change.ChangeSet):
+                result = self._search_for_change_contents(change_.changes,
+                                                          file)
+                if result is not None:
+                    return result
+            if isinstance(change_, change.ChangeContents) and \
+               change_.resource == file:
+                return change_.old_contents
+
+    def write(self):
+        if self.save:
+            data = []
+            to_data = change.ChangeToData()
+            self._remove_extra_items()
+            data.append([to_data(change_) for change_ in self.undo_list])
+            data.append([to_data(change_) for change_ in self.redo_list])
+            self.project.data_files.write_data('history', data,
+                                               compress=self.compress)
+
+    def get_file_undo_list(self, resource):
+        result = []
+        for change in self.undo_list:
+            if resource in change.get_changed_resources():
+                result.append(change)
+        return result
+
+    def __str__(self):
+        return 'History holds %s changes in memory' % \
+               (len(self.undo_list) + len(self.redo_list))
+
+    undo_list = property(lambda self: self._undo_list)
+    redo_list = property(lambda self: self._redo_list)
+
+    @property
+    def tobe_undone(self):
+        """The last done change if available, `None` otherwise"""
+        if self.undo_list:
+            return self.undo_list[-1]
+
+    @property
+    def tobe_redone(self):
+        """The last undone change if available, `None` otherwise"""
+        if self.redo_list:
+            return self.redo_list[-1]
+
+    @property
+    def max_undos(self):
+        if self._maxundos is None:
+            return self.project.prefs.get('max_history_items', 100)
+        else:
+            return self._maxundos
+
+    @property
+    def save(self):
+        return self.project.prefs.get('save_history', False)
+
+    @property
+    def compress(self):
+        return self.project.prefs.get('compress_history', False)
+
+    def clear(self):
+        """Forget all undo and redo information"""
+        del self.undo_list[:]
+        del self.redo_list[:]
+
+
+class _FindChangeDependencies(object):
+
+    def __init__(self, change_list):
+        self.change = change_list[0]
+        self.change_list = change_list
+        self.changed_resources = set(self.change.get_changed_resources())
+
+    def __call__(self):
+        result = [self.change]
+        for change in self.change_list[1:]:
+            if self._depends_on(change, result):
+                result.append(change)
+                self.changed_resources.update(change.get_changed_resources())
+        return result
+
+    def _depends_on(self, changes, result):
+        for resource in changes.get_changed_resources():
+            if resource is None:
+                continue
+            if resource in self.changed_resources:
+                return True
+            for changed in self.changed_resources:
+                if resource.is_folder() and resource.contains(changed):
+                    return True
+                if changed.is_folder() and changed.contains(resource):
+                    return True
+        return False
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/libutils.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,65 @@
+"""A few useful functions for using rope as a library"""
+import os.path
+
+import rope.base.project
+import rope.base.pycore
+from rope.base import taskhandle
+
+
+def path_to_resource(project, path, type=None):
+    """Get the resource at path
+
+    You only need to specify `type` if `path` does not exist.  It can
+    be either 'file' or 'folder'.  If the type is `None` it is assumed
+    that the resource already exists.
+
+    Note that this function uses `Project.get_resource()`,
+    `Project.get_file()`, and `Project.get_folder()` methods.
+
+    """
+    project_path = relative(project.address, path)
+    if project_path is None:
+        project_path = rope.base.project._realpath(path)
+        project = rope.base.project.get_no_project()
+    if type is None:
+        return project.get_resource(project_path)
+    if type == 'file':
+        return project.get_file(project_path)
+    if type == 'folder':
+        return project.get_folder(project_path)
+    return None
+
+def relative(root, path):
+    root = rope.base.project._realpath(root).replace(os.path.sep, '/')
+    path = rope.base.project._realpath(path).replace(os.path.sep, '/')
+    if path == root:
+    	return ''
+    if path.startswith(root + '/'):
+    	return path[len(root) + 1:]
+
+def report_change(project, path, old_content):
+    """Report that the contents of file at `path` was changed
+
+    The new contents of file is retrieved by reading the file.
+
+    """
+    resource = path_to_resource(project, path)
+    if resource is None:
+        return
+    for observer in list(project.observers):
+        observer.resource_changed(resource)
+    if project.pycore.automatic_soa:
+        rope.base.pycore.perform_soa_on_changed_scopes(project, resource,
+                                                       old_content)
+
+def analyze_modules(project, task_handle=taskhandle.NullTaskHandle()):
+    """Perform static object analysis on all python files in the project
+
+    Note that this might be really time consuming.
+    """
+    resources = project.pycore.get_python_files()
+    job_set = task_handle.create_jobset('Analyzing Modules', len(resources))
+    for resource in resources:
+        job_set.started_job(resource.path)
+        project.pycore.analyze_module(resource)
+        job_set.finished_job()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/oi/__init__.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,38 @@
+"""Rope object analysis and inference package
+
+Rope makes some simplifying assumptions about a python program.  It
+assumes that a program only performs assignments and function calls.
+Tracking assignments is simple and `PyName` objects handle that.  The
+main problem is function calls.  Rope uses these two approaches for
+obtaining call information:
+
+* Static object analysis: `rope.base.pycore.PyCore.analyze_module()`
+
+  It can analyze modules to obtain information about functions.  This
+  is done by analyzing function calls in a module or scope.  Currently
+  SOA analyzes the scopes that are changed while saving or when the
+  user asks to analyze a module.  That is mainly because static
+  analysis is time-consuming.
+
+* Dynamic object analysis: `rope.base.pycore.PyCore.run_module()`
+
+  When you run a module or your testsuite, when DOA is enabled, it
+  collects information about parameters passed to and objects returned
+  from functions.  The main problem with this approach is that it is
+  quite slow; Not when looking up the information but when collecting
+  them.
+
+An instance of `rope.base.oi.objectinfo.ObjectInfoManager` can be used
+for accessing these information.  It saves the data in a
+`rope.base.oi.objectdb.ObjectDB` internally.
+
+Now if our objectdb does not know anything about a function and we
+need the value returned by it, static object inference, SOI, comes
+into play.  It analyzes function body and tries to infer the object
+that is returned from it (we usually need the returned value for the
+given parameter objects).
+
+Rope might collect and store information for other `PyName`\s, too.
+For instance rope stores the object builtin containers hold.
+
+"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/oi/doa.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,162 @@
+import cPickle as pickle
+import marshal
+import os
+import socket
+import subprocess
+import sys
+import tempfile
+import threading
+
+
+class PythonFileRunner(object):
+    """A class for running python project files"""
+
+    def __init__(self, pycore, file_, args=None, stdin=None,
+                 stdout=None, analyze_data=None):
+        self.pycore = pycore
+        self.file = file_
+        self.analyze_data = analyze_data
+        self.observers = []
+        self.args = args
+        self.stdin = stdin
+        self.stdout = stdout
+
+    def run(self):
+        """Execute the process"""
+        env = dict(os.environ)
+        file_path = self.file.real_path
+        path_folders = self.pycore.get_source_folders() + \
+                       self.pycore.get_python_path_folders()
+        env['PYTHONPATH'] = os.pathsep.join(folder.real_path
+                                            for folder in path_folders)
+        runmod_path = self.pycore.find_module('rope.base.oi.runmod').real_path
+        self.receiver = None
+        self._init_data_receiving()
+        send_info = '-'
+        if self.receiver:
+            send_info = self.receiver.get_send_info()
+        args = [sys.executable, runmod_path, send_info,
+                self.pycore.project.address, self.file.real_path]
+        if self.analyze_data is None:
+            del args[1:4]
+        if self.args is not None:
+            args.extend(self.args)
+        self.process = subprocess.Popen(
+            executable=sys.executable, args=args, env=env,
+            cwd=os.path.split(file_path)[0], stdin=self.stdin,
+            stdout=self.stdout, stderr=self.stdout, close_fds=os.name != 'nt')
+
+    def _init_data_receiving(self):
+        if self.analyze_data is None:
+            return
+        # Disabling FIFO data transfer due to blocking when running
+        # unittests in the GUI.
+        # XXX: Handle FIFO data transfer for `rope.ui.testview`
+        if True or os.name == 'nt':
+            self.receiver = _SocketReceiver()
+        else:
+            self.receiver = _FIFOReceiver()
+        self.receiving_thread = threading.Thread(target=self._receive_information)
+        self.receiving_thread.setDaemon(True)
+        self.receiving_thread.start()
+
+    def _receive_information(self):
+        #temp = open('/dev/shm/info', 'w')
+        for data in self.receiver.receive_data():
+            self.analyze_data(data)
+            #temp.write(str(data) + '\n')
+        #temp.close()
+        for observer in self.observers:
+            observer()
+
+    def wait_process(self):
+        """Wait for the process to finish"""
+        self.process.wait()
+        if self.analyze_data:
+            self.receiving_thread.join()
+
+    def kill_process(self):
+        """Stop the process"""
+        if self.process.poll() is not None:
+            return
+        try:
+            if hasattr(self.process, 'terminate'):
+                self.process.terminate()
+            elif os.name != 'nt':
+                os.kill(self.process.pid, 9)
+            else:
+                import ctypes
+                handle = int(self.process._handle)
+                ctypes.windll.kernel32.TerminateProcess(handle, -1)
+        except OSError:
+            pass
+
+    def add_finishing_observer(self, observer):
+        """Notify this observer when execution finishes"""
+        self.observers.append(observer)
+
+
+class _MessageReceiver(object):
+
+    def receive_data(self):
+        pass
+
+    def get_send_info(self):
+        pass
+
+
+class _SocketReceiver(_MessageReceiver):
+
+    def __init__(self):
+        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.data_port = 3037
+        while self.data_port < 4000:
+            try:
+                self.server_socket.bind(('', self.data_port))
+                break
+            except socket.error, e:
+                self.data_port += 1
+        self.server_socket.listen(1)
+
+    def get_send_info(self):
+        return str(self.data_port)
+
+    def receive_data(self):
+        conn, addr = self.server_socket.accept()
+        self.server_socket.close()
+        my_file = conn.makefile('r')
+        while True:
+            try:
+                yield pickle.load(my_file)
+            except EOFError:
+                break
+        my_file.close()
+        conn.close()
+
+
+class _FIFOReceiver(_MessageReceiver):
+
+    def __init__(self):
+        # XXX: this is insecure and might cause race conditions
+        self.file_name = self._get_file_name()
+        os.mkfifo(self.file_name)
+
+    def _get_file_name(self):
+        prefix = tempfile.gettempdir() + '/__rope_'
+        i = 0
+        while os.path.exists(prefix + str(i).rjust(4, '0')):
+            i += 1
+        return prefix + str(i).rjust(4, '0')
+
+    def get_send_info(self):
+        return self.file_name
+
+    def receive_data(self):
+        my_file = open(self.file_name, 'rb')
+        while True:
+            try:
+                yield marshal.load(my_file)
+            except EOFError:
+                break
+        my_file.close()
+        os.remove(self.file_name)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/oi/memorydb.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,106 @@
+from rope.base.oi import objectdb
+
+
+class MemoryDB(objectdb.FileDict):
+
+    def __init__(self, project, persist=None):
+        self.project = project
+        self._persist = persist
+        self.files = self
+        self._load_files()
+        self.project.data_files.add_write_hook(self.write)
+
+    def _load_files(self):
+        self._files = {}
+        if self.persist:
+            result = self.project.data_files.read_data(
+                'objectdb', compress=self.compress, import_=True)
+            if result is not None:
+                self._files = result
+
+    def keys(self):
+        return self._files.keys()
+
+    def __contains__(self, key):
+        return key in self._files
+
+    def __getitem__(self, key):
+        return FileInfo(self._files[key])
+
+    def create(self, path):
+        self._files[path] = {}
+
+    def rename(self, file, newfile):
+        if file not in self._files:
+            return
+        self._files[newfile] = self._files[file]
+        del self[file]
+
+    def __delitem__(self, file):
+        del self._files[file]
+
+    def write(self):
+        if self.persist:
+            self.project.data_files.write_data('objectdb', self._files,
+                                               self.compress)
+
+    @property
+    def compress(self):
+        return self.project.prefs.get('compress_objectdb', False)
+
+    @property
+    def persist(self):
+        if self._persist is not None:
+            return self._persist
+        else:
+            return self.project.prefs.get('save_objectdb', False)
+
+
+class FileInfo(objectdb.FileInfo):
+
+    def __init__(self, scopes):
+        self.scopes = scopes
+
+    def create_scope(self, key):
+        self.scopes[key] = ScopeInfo()
+
+    def keys(self):
+        return self.scopes.keys()
+
+    def __contains__(self, key):
+        return key in self.scopes
+
+    def __getitem__(self, key):
+        return self.scopes[key]
+
+    def __delitem__(self, key):
+        del self.scopes[key]
+
+
+class ScopeInfo(objectdb.ScopeInfo):
+
+    def __init__(self):
+        self.call_info = {}
+        self.per_name = {}
+
+    def get_per_name(self, name):
+        return self.per_name.get(name, None)
+
+    def save_per_name(self, name, value):
+        self.per_name[name] = value
+
+    def get_returned(self, parameters):
+        return self.call_info.get(parameters, None)
+
+    def get_call_infos(self):
+        for args, returned in self.call_info.items():
+            yield objectdb.CallInfo(args, returned)
+
+    def add_call(self, parameters, returned):
+        self.call_info[parameters] = returned
+
+    def __getstate__(self):
+        return (self.call_info, self.per_name)
+
+    def __setstate__(self, data):
+        self.call_info, self.per_name = data
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/oi/objectdb.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,175 @@
+import UserDict
+
+
+class ObjectDB(object):
+
+    def __init__(self, db, validation):
+        self.db = db
+        self.validation = validation
+        self.observers = []
+        self.files = db.files
+
+    def validate_files(self):
+        for file in list(self.files):
+            if not self.validation.is_file_valid(file):
+                del self.files[file]
+                self._file_removed(file)
+
+    def validate_file(self, file):
+        if file not in self.files:
+            return
+        for key in list(self.files[file]):
+            if not self.validation.is_scope_valid(file, key):
+                del self.files[file][key]
+
+    def file_moved(self, file, newfile):
+        if file not in self.files:
+            return
+        self.files.rename(file, newfile)
+        self._file_removed(file)
+        self._file_added(newfile)
+
+    def get_files(self):
+        return self.files.keys()
+
+    def get_returned(self, path, key, args):
+        scope_info = self._get_scope_info(path, key, readonly=True)
+        result = scope_info.get_returned(args)
+        if self.validation.is_value_valid(result):
+            return result
+
+    def get_pername(self, path, key, name):
+        scope_info = self._get_scope_info(path, key, readonly=True)
+        result = scope_info.get_per_name(name)
+        if self.validation.is_value_valid(result):
+            return result
+
+    def get_callinfos(self, path, key):
+        scope_info = self._get_scope_info(path, key, readonly=True)
+        return scope_info.get_call_infos()
+
+    def add_callinfo(self, path, key, args, returned):
+        scope_info = self._get_scope_info(path, key, readonly=False)
+        old_returned = scope_info.get_returned(args)
+        if self.validation.is_more_valid(returned, old_returned):
+            scope_info.add_call(args, returned)
+
+    def add_pername(self, path, key, name, value):
+        scope_info = self._get_scope_info(path, key, readonly=False)
+        old_value = scope_info.get_per_name(name)
+        if self.validation.is_more_valid(value, old_value):
+            scope_info.save_per_name(name, value)
+
+    def add_file_list_observer(self, observer):
+        self.observers.append(observer)
+
+    def write(self):
+        self.db.write()
+
+    def _get_scope_info(self, path, key, readonly=True):
+        if path not in self.files:
+            if readonly:
+                return _NullScopeInfo()
+            self.files.create(path)
+            self._file_added(path)
+        if key not in self.files[path]:
+            if readonly:
+                return _NullScopeInfo()
+            self.files[path].create_scope(key)
+        result = self.files[path][key]
+        if isinstance(result, dict):
+            print self.files, self.files[path], self.files[path][key]
+        return result
+
+    def _file_removed(self, path):
+        for observer in self.observers:
+            observer.removed(path)
+
+    def _file_added(self, path):
+        for observer in self.observers:
+            observer.added(path)
+
+    def __str__(self):
+        scope_count = 0
+        for file_dict in self.files.values():
+            scope_count += len(file_dict)
+        return 'ObjectDB holds %s file and %s scope infos' % \
+               (len(self.files), scope_count)
+
+
+class _NullScopeInfo(object):
+
+    def __init__(self, error_on_write=True):
+        self.error_on_write = error_on_write
+
+    def get_per_name(self, name):
+        pass
+
+    def save_per_name(self, name, value):
+        if self.error_on_write:
+            raise NotImplementedError()
+
+    def get_returned(self, parameters):
+        pass
+
+    def get_call_infos(self):
+        return []
+
+    def add_call(self, parameters, returned):
+        if self.error_on_write:
+            raise NotImplementedError()
+
+
+class FileInfo(UserDict.DictMixin):
+
+    def create_scope(self, key):
+        pass
+
+
+class FileDict(UserDict.DictMixin):
+
+    def create(self, key):
+        pass
+
+    def rename(self, key, new_key):
+        pass
+
+
+class ScopeInfo(object):
+
+    def get_per_name(self, name):
+        pass
+
+    def save_per_name(self, name, value):
+        pass
+
+    def get_returned(self, parameters):
+        pass
+
+    def get_call_infos(self):
+        pass
+
+    def add_call(self, parameters, returned):
+        pass
+
+
+class CallInfo(object):
+
+    def __init__(self, args, returned):
+        self.args = args
+        self.returned = returned
+
+    def get_parameters(self):
+        return self.args
+
+    def get_returned(self):
+        return self.returned
+
+
+class FileListObserver(object):
+
+    def added(self, path):
+        pass
+
+    def removed(self, path):
+        pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/oi/objectinfo.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,232 @@
+import warnings
+
+from rope.base import exceptions, resourceobserver
+from rope.base.oi import objectdb, memorydb, transform
+
+
+class ObjectInfoManager(object):
+    """Stores object information
+
+    It uses an instance of `objectdb.ObjectDB` for storing
+    information.
+
+    """
+
+    def __init__(self, project):
+        self.project = project
+        self.to_textual = transform.PyObjectToTextual(project)
+        self.to_pyobject = transform.TextualToPyObject(project)
+        self.doi_to_pyobject = transform.DOITextualToPyObject(project)
+        self._init_objectdb()
+        if project.prefs.get('validate_objectdb', False):
+            self._init_validation()
+
+    def _init_objectdb(self):
+        dbtype = self.project.get_prefs().get('objectdb_type', None)
+        persist = None
+        if dbtype is not None:
+            warnings.warn(
+                '"objectdb_type" project config is deprecated;\n'
+                'Use "save_objectdb" instead in your project '
+                'config file.\n(".ropeproject/config.py" by default)\n',
+                DeprecationWarning)
+            if dbtype != 'memory' and self.project.ropefolder is not None:
+                persist = True
+        self.validation = TextualValidation(self.to_pyobject)
+        db = memorydb.MemoryDB(self.project, persist=persist)
+        self.objectdb = objectdb.ObjectDB(db, self.validation)
+
+    def _init_validation(self):
+        self.objectdb.validate_files()
+        observer = resourceobserver.ResourceObserver(
+            changed=self._resource_changed, moved=self._resource_moved,
+            removed=self._resource_moved)
+        files = []
+        for path in self.objectdb.get_files():
+            resource = self.to_pyobject.path_to_resource(path)
+            if resource is not None and resource.project == self.project:
+                files.append(resource)
+        self.observer = resourceobserver.FilteredResourceObserver(observer,
+                                                                  files)
+        self.objectdb.add_file_list_observer(_FileListObserver(self))
+        self.project.add_observer(self.observer)
+
+    def _resource_changed(self, resource):
+        try:
+            self.objectdb.validate_file(
+                self.to_textual.resource_to_path(resource))
+        except exceptions.ModuleSyntaxError:
+            pass
+
+    def _resource_moved(self, resource, new_resource=None):
+        self.observer.remove_resource(resource)
+        if new_resource is not None:
+            old = self.to_textual.resource_to_path(resource)
+            new = self.to_textual.resource_to_path(new_resource)
+            self.objectdb.file_moved(old, new)
+            self.observer.add_resource(new_resource)
+
+    def get_returned(self, pyobject, args):
+        result = self.get_exact_returned(pyobject, args)
+        if result is not None:
+            return result
+        path, key = self._get_scope(pyobject)
+        if path is None:
+            return None
+        for call_info in self.objectdb.get_callinfos(path, key):
+            returned = call_info.get_returned()
+            if returned and returned[0] not in ('unknown', 'none'):
+                result = returned
+                break
+            if result is None:
+                result = returned
+        if result is not None:
+            return self.to_pyobject(result)
+
+    def get_exact_returned(self, pyobject, args):
+        path, key = self._get_scope(pyobject)
+        if path is not None:
+            returned = self.objectdb.get_returned(
+                path, key, self._args_to_textual(pyobject, args))
+            if returned is not None:
+                return self.to_pyobject(returned)
+
+    def _args_to_textual(self, pyfunction, args):
+        parameters = list(pyfunction.get_param_names(special_args=False))
+        arguments = args.get_arguments(parameters)[:len(parameters)]
+        textual_args = tuple([self.to_textual(arg)
+                              for arg in arguments])
+        return textual_args
+
+    def get_parameter_objects(self, pyobject):
+        path, key = self._get_scope(pyobject)
+        if path is None:
+            return None
+        arg_count = len(pyobject.get_param_names(special_args=False))
+        unknowns = arg_count
+        parameters = [None] * arg_count
+        for call_info in self.objectdb.get_callinfos(path, key):
+            args = call_info.get_parameters()
+            for index, arg in enumerate(args[:arg_count]):
+                old = parameters[index]
+                if self.validation.is_more_valid(arg, old):
+                    parameters[index] = arg
+                    if self.validation.is_value_valid(arg):
+                        unknowns -= 1
+            if unknowns == 0:
+                break
+        if unknowns < arg_count:
+            return [self.to_pyobject(parameter)
+                    for parameter in parameters]
+
+    def get_passed_objects(self, pyfunction, parameter_index):
+        path, key = self._get_scope(pyfunction)
+        if path is None:
+            return []
+        result = []
+        for call_info in self.objectdb.get_callinfos(path, key):
+            args = call_info.get_parameters()
+            if len(args) > parameter_index:
+                parameter = self.to_pyobject(args[parameter_index])
+                if parameter is not None:
+                    result.append(parameter)
+        return result
+
+    def doa_data_received(self, data):
+        def doi_to_normal(textual):
+            pyobject = self.doi_to_pyobject(textual)
+            return self.to_textual(pyobject)
+        function = doi_to_normal(data[0])
+        args = tuple([doi_to_normal(textual) for textual in data[1]])
+        returned = doi_to_normal(data[2])
+        if function[0] == 'defined' and len(function) == 3:
+            self._save_data(function, args, returned)
+
+    def function_called(self, pyfunction, params, returned=None):
+        function_text = self.to_textual(pyfunction)
+        params_text = tuple([self.to_textual(param)
+                             for param in params])
+        returned_text = ('unknown',)
+        if returned is not None:
+            returned_text = self.to_textual(returned)
+        self._save_data(function_text, params_text, returned_text)
+
+    def save_per_name(self, scope, name, data):
+        path, key = self._get_scope(scope.pyobject)
+        if path is not None:
+            self.objectdb.add_pername(path, key, name, self.to_textual(data))
+
+    def get_per_name(self, scope, name):
+        path, key = self._get_scope(scope.pyobject)
+        if path is not None:
+            result = self.objectdb.get_pername(path, key, name)
+            if result is not None:
+                return self.to_pyobject(result)
+
+    def _save_data(self, function, args, returned=('unknown',)):
+        self.objectdb.add_callinfo(function[1], function[2], args, returned)
+
+    def _get_scope(self, pyobject):
+        resource = pyobject.get_module().get_resource()
+        if resource is None:
+            return None, None
+        textual = self.to_textual(pyobject)
+        if textual[0] == 'defined':
+            path = textual[1]
+            if len(textual) == 3:
+                key = textual[2]
+            else:
+                key = ''
+            return path, key
+        return None, None
+
+    def sync(self):
+        self.objectdb.sync()
+
+    def __str__(self):
+        return str(self.objectdb)
+
+
+class TextualValidation(object):
+
+    def __init__(self, to_pyobject):
+        self.to_pyobject = to_pyobject
+
+    def is_value_valid(self, value):
+        # ???: Should none and unknown be considered valid?
+        if value is None or value[0] in ('none', 'unknown'):
+            return False
+        return self.to_pyobject(value) is not None
+
+    def is_more_valid(self, new, old):
+        if old is None:
+            return True
+        return new[0] not in ('unknown', 'none')
+
+    def is_file_valid(self, path):
+        return self.to_pyobject.path_to_resource(path) is not None
+
+    def is_scope_valid(self, path, key):
+        if key == '':
+            textual = ('defined', path)
+        else:
+            textual = ('defined', path, key)
+        return self.to_pyobject(textual) is not None
+
+
+class _FileListObserver(object):
+
+    def __init__(self, object_info):
+        self.object_info = object_info
+        self.observer = self.object_info.observer
+        self.to_pyobject = self.object_info.to_pyobject
+
+    def removed(self, path):
+        resource = self.to_pyobject.path_to_resource(path)
+        if resource is not None:
+            self.observer.remove_resource(resource)
+
+    def added(self, path):
+        resource = self.to_pyobject.path_to_resource(path)
+        if resource is not None:
+            self.observer.add_resource(resource)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/oi/runmod.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,210 @@
+
+def __rope_start_everything():
+    import os
+    import sys
+    import socket
+    import cPickle as pickle
+    import marshal
+    import inspect
+    import types
+    import threading
+
+    class _MessageSender(object):
+
+        def send_data(self, data):
+            pass
+
+    class _SocketSender(_MessageSender):
+
+        def __init__(self, port):
+            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            s.connect(('127.0.0.1', port))
+            self.my_file = s.makefile('w')
+
+        def send_data(self, data):
+            if not self.my_file.closed:
+                pickle.dump(data, self.my_file)
+
+        def close(self):
+            self.my_file.close()
+
+    class _FileSender(_MessageSender):
+
+        def __init__(self, file_name):
+            self.my_file = open(file_name, 'wb')
+
+        def send_data(self, data):
+            if not self.my_file.closed:
+                marshal.dump(data, self.my_file)
+
+        def close(self):
+            self.my_file.close()
+
+
+    def _cached(func):
+        cache = {}
+        def newfunc(self, arg):
+            if arg in cache:
+                return cache[arg]
+            result = func(self, arg)
+            cache[arg] = result
+            return result
+        return newfunc
+
+    class _FunctionCallDataSender(object):
+
+        def __init__(self, send_info, project_root):
+            self.project_root = project_root
+            if send_info.isdigit():
+                self.sender = _SocketSender(int(send_info))
+            else:
+                self.sender = _FileSender(send_info)
+
+            def global_trace(frame, event, arg):
+                # HACK: Ignoring out->in calls
+                # This might lose some information
+                if self._is_an_interesting_call(frame):
+                    return self.on_function_call
+            sys.settrace(global_trace)
+            threading.settrace(global_trace)
+
+        def on_function_call(self, frame, event, arg):
+            if event != 'return':
+                return
+            args = []
+            returned = ('unknown',)
+            code = frame.f_code
+            for argname in code.co_varnames[:code.co_argcount]:
+                try:
+                    args.append(self._object_to_persisted_form(frame.f_locals[argname]))
+                except (TypeError, AttributeError):
+                    args.append(('unknown',))
+            try:
+                returned = self._object_to_persisted_form(arg)
+            except (TypeError, AttributeError):
+                pass
+            try:
+                data = (self._object_to_persisted_form(frame.f_code),
+                        tuple(args), returned)
+                self.sender.send_data(data)
+            except (TypeError):
+                pass
+            return self.on_function_call
+
+        def _is_an_interesting_call(self, frame):
+            #if frame.f_code.co_name in ['?', '<module>']:
+            #    return False
+            #return not frame.f_back or not self._is_code_inside_project(frame.f_back.f_code)
+
+            if not self._is_code_inside_project(frame.f_code) and \
+               (not frame.f_back or not self._is_code_inside_project(frame.f_back.f_code)):
+                return False
+            return True
+
+        def _is_code_inside_project(self, code):
+            source = self._path(code.co_filename)
+            return source is not None and os.path.exists(source) and \
+                   _realpath(source).startswith(self.project_root)
+
+        @_cached
+        def _get_persisted_code(self, object_):
+            source = self._path(object_.co_filename)
+            if not os.path.exists(source):
+                raise TypeError('no source')
+            return ('defined', _realpath(source), str(object_.co_firstlineno))
+
+        @_cached
+        def _get_persisted_class(self, object_):
+            try:
+                return ('defined', _realpath(inspect.getsourcefile(object_)),
+                        object_.__name__)
+            except (TypeError, AttributeError):
+                return ('unknown',)
+
+        def _get_persisted_builtin(self, object_):
+            if isinstance(object_, (str, unicode)):
+                return ('builtin', 'str')
+            if isinstance(object_, list):
+                holding = None
+                if len(object_) > 0:
+                    holding = object_[0]
+                return ('builtin', 'list', self._object_to_persisted_form(holding))
+            if isinstance(object_, dict):
+                keys = None
+                values = None
+                if len(object_) > 0:
+                    keys = object_.keys()[0]
+                    values = object_[keys]
+                return ('builtin', 'dict',
+                        self._object_to_persisted_form(keys),
+                        self._object_to_persisted_form(values))
+            if isinstance(object_, tuple):
+                objects = []
+                if len(object_) < 3:
+                    for holding in object_:
+                        objects.append(self._object_to_persisted_form(holding))
+                else:
+                    objects.append(self._object_to_persisted_form(object_[0]))
+                return tuple(['builtin', 'tuple'] + objects)
+            if isinstance(object_, set):
+                holding = None
+                if len(object_) > 0:
+                    for o in object_:
+                        holding = o
+                        break
+                return ('builtin', 'set', self._object_to_persisted_form(holding))
+            return ('unknown',)
+
+        def _object_to_persisted_form(self, object_):
+            if object_ is None:
+                return ('none',)
+            if isinstance(object_, types.CodeType):
+                return self._get_persisted_code(object_)
+            if isinstance(object_, types.FunctionType):
+                return self._get_persisted_code(object_.func_code)
+            if isinstance(object_, types.MethodType):
+                return self._get_persisted_code(object_.im_func.func_code)
+            if isinstance(object_, types.ModuleType):
+                return self._get_persisted_module(object_)
+            if isinstance(object_, (str, unicode, list, dict, tuple, set)):
+                return self._get_persisted_builtin(object_)
+            if isinstance(object_, (types.TypeType, types.ClassType)):
+                return self._get_persisted_class(object_)
+            return ('instance', self._get_persisted_class(type(object_)))
+
+        @_cached
+        def _get_persisted_module(self, object_):
+            path = self._path(object_.__file__)
+            if path and os.path.exists(path):
+                return ('defined', _realpath(path))
+            return ('unknown',)
+
+        def _path(self, path):
+            if path.endswith('.pyc'):
+                path = path[:-1]
+            if path.endswith('.py'):
+                return path
+
+        def close(self):
+            self.sender.close()
+
+    def _realpath(path):
+        return os.path.realpath(os.path.abspath(os.path.expanduser(path)))
+
+    send_info = sys.argv[1]
+    project_root = sys.argv[2]
+    file_to_run = sys.argv[3]
+    run_globals = globals()
+    run_globals.update({'__name__': '__main__',
+                        '__builtins__': __builtins__,
+                        '__file__': file_to_run})
+    if send_info != '-':
+        data_sender = _FunctionCallDataSender(send_info, project_root)
+    del sys.argv[1:4]
+    execfile(file_to_run, run_globals)
+    if send_info != '-':
+        data_sender.close()
+
+
+if __name__ == '__main__':
+    __rope_start_everything()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/oi/soa.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,136 @@
+import rope.base.ast
+import rope.base.oi.soi
+import rope.base.pynames
+from rope.base import pyobjects, evaluate, astutils, arguments
+
+
+def analyze_module(pycore, pymodule, should_analyze,
+                   search_subscopes, followed_calls):
+    """Analyze `pymodule` for static object inference
+
+    Analyzes scopes for collecting object information.  The analysis
+    starts from inner scopes.
+
+    """
+    _analyze_node(pycore, pymodule, should_analyze,
+                  search_subscopes, followed_calls)
+
+
+def _analyze_node(pycore, pydefined, should_analyze,
+                  search_subscopes, followed_calls):
+    if search_subscopes(pydefined):
+        for scope in pydefined.get_scope().get_scopes():
+            _analyze_node(pycore, scope.pyobject, should_analyze,
+                          search_subscopes, followed_calls)
+    if should_analyze(pydefined):
+        new_followed_calls = max(0, followed_calls - 1)
+        return_true = lambda pydefined: True
+        return_false = lambda pydefined: False
+        def _follow(pyfunction):
+            _analyze_node(pycore, pyfunction, return_true,
+                          return_false, new_followed_calls)
+        if not followed_calls:
+            _follow = None
+        visitor = SOAVisitor(pycore, pydefined, _follow)
+        for child in rope.base.ast.get_child_nodes(pydefined.get_ast()):
+            rope.base.ast.walk(child, visitor)
+
+
+class SOAVisitor(object):
+
+    def __init__(self, pycore, pydefined, follow_callback=None):
+        self.pycore = pycore
+        self.pymodule = pydefined.get_module()
+        self.scope = pydefined.get_scope()
+        self.follow = follow_callback
+
+    def _FunctionDef(self, node):
+        pass
+
+    def _ClassDef(self, node):
+        pass
+
+    def _Call(self, node):
+        for child in rope.base.ast.get_child_nodes(node):
+            rope.base.ast.walk(child, self)
+        primary, pyname = evaluate.eval_node2(self.scope, node.func)
+        if pyname is None:
+            return
+        pyfunction = pyname.get_object()
+        if isinstance(pyfunction, pyobjects.AbstractFunction):
+            args = arguments.create_arguments(primary, pyfunction,
+                                              node, self.scope)
+        elif isinstance(pyfunction, pyobjects.PyClass):
+            pyclass = pyfunction
+            if '__init__' in pyfunction:
+                pyfunction = pyfunction['__init__'].get_object()
+            pyname = rope.base.pynames.UnboundName(pyobjects.PyObject(pyclass))
+            args = self._args_with_self(primary, pyname, pyfunction, node)
+        elif '__call__' in pyfunction:
+            pyfunction = pyfunction['__call__'].get_object()
+            args = self._args_with_self(primary, pyname, pyfunction, node)
+        else:
+            return
+        self._call(pyfunction, args)
+
+    def _args_with_self(self, primary, self_pyname, pyfunction, node):
+        base_args = arguments.create_arguments(primary, pyfunction,
+                                               node, self.scope)
+        return arguments.MixedArguments(self_pyname, base_args, self.scope)
+
+    def _call(self, pyfunction, args):
+        if isinstance(pyfunction, pyobjects.PyFunction):
+            if self.follow is not None:
+                before = self._parameter_objects(pyfunction)
+            self.pycore.object_info.function_called(
+                pyfunction, args.get_arguments(pyfunction.get_param_names()))
+            pyfunction._set_parameter_pyobjects(None)
+            if self.follow is not None:
+                after = self._parameter_objects(pyfunction)
+                if after != before:
+                    self.follow(pyfunction)
+        # XXX: Maybe we should not call every builtin function
+        if isinstance(pyfunction, rope.base.builtins.BuiltinFunction):
+            pyfunction.get_returned_object(args)
+
+    def _parameter_objects(self, pyfunction):
+        result = []
+        for i in range(len(pyfunction.get_param_names(False))):
+            result.append(pyfunction.get_parameter(i))
+        return result
+
+    def _Assign(self, node):
+        for child in rope.base.ast.get_child_nodes(node):
+            rope.base.ast.walk(child, self)
+        visitor = _SOAAssignVisitor()
+        nodes = []
+        for child in node.targets:
+            rope.base.ast.walk(child, visitor)
+            nodes.extend(visitor.nodes)
+        for subscript, levels in nodes:
+            instance = evaluate.eval_node(self.scope, subscript.value)
+            args_pynames = []
+            args_pynames.append(evaluate.eval_node(self.scope,
+                                                   subscript.slice.value))
+            value = rope.base.oi.soi._infer_assignment(
+                rope.base.pynames.AssignmentValue(node.value, levels), self.pymodule)
+            args_pynames.append(rope.base.pynames.UnboundName(value))
+            if instance is not None and value is not None:
+                pyobject = instance.get_object()
+                if '__setitem__' in pyobject:
+                    pyfunction = pyobject['__setitem__'].get_object()
+                    args = arguments.ObjectArguments([instance] + args_pynames)
+                    self._call(pyfunction, args)
+                # IDEA: handle `__setslice__`, too
+
+
+class _SOAAssignVisitor(astutils._NodeNameCollector):
+
+    def __init__(self):
+        super(_SOAAssignVisitor, self).__init__()
+        self.nodes = []
+
+    def _added(self, node, levels):
+        if isinstance(node, rope.base.ast.Subscript) and \
+           isinstance(node.slice, rope.base.ast.Index):
+            self.nodes.append((node, levels))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/oi/soi.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,186 @@
+"""A module for inferring objects
+
+For more information see the documentation in `rope.base.oi`
+package.
+
+"""
+import rope.base.builtins
+import rope.base.pynames
+import rope.base.pyobjects
+from rope.base import evaluate, utils, arguments
+
+
+_ignore_inferred = utils.ignore_exception(
+    rope.base.pyobjects.IsBeingInferredError)
+
+
+@_ignore_inferred
+def infer_returned_object(pyfunction, args):
+    """Infer the `PyObject` this `PyFunction` returns after calling"""
+    object_info = pyfunction.pycore.object_info
+    result = object_info.get_exact_returned(pyfunction, args)
+    if result is not None:
+        return result
+    result = _infer_returned(pyfunction, args)
+    if result is not None:
+        if args and pyfunction.get_module().get_resource() is not None:
+            params = args.get_arguments(
+                pyfunction.get_param_names(special_args=False))
+            object_info.function_called(pyfunction, params, result)
+        return result
+    return object_info.get_returned(pyfunction, args)
+
+@_ignore_inferred
+def infer_parameter_objects(pyfunction):
+    """Infer the `PyObject`\s of parameters of this `PyFunction`"""
+    object_info = pyfunction.pycore.object_info
+    result = object_info.get_parameter_objects(pyfunction)
+    if result is None:
+        result = _parameter_objects(pyfunction)
+    _handle_first_parameter(pyfunction, result)
+    return result
+
+def _handle_first_parameter(pyobject, parameters):
+    kind = pyobject.get_kind()
+    if parameters is None or kind not in ['method', 'classmethod']:
+        pass
+    if not parameters:
+        if not pyobject.get_param_names(special_args=False):
+            return
+        parameters.append(rope.base.pyobjects.get_unknown())
+    if kind == 'method':
+        parameters[0] = rope.base.pyobjects.PyObject(pyobject.parent)
+    if kind == 'classmethod':
+        parameters[0] = pyobject.parent
+
+@_ignore_inferred
+def infer_assigned_object(pyname):
+    if not pyname.assignments:
+        return
+    for assignment in reversed(pyname.assignments):
+        result = _infer_assignment(assignment, pyname.module)
+        if result is not None:
+            return result
+
+def get_passed_objects(pyfunction, parameter_index):
+    object_info = pyfunction.pycore.object_info
+    result = object_info.get_passed_objects(pyfunction,
+                                            parameter_index)
+    if not result:
+        statically_inferred = _parameter_objects(pyfunction)
+        if len(statically_inferred) > parameter_index:
+            result.append(statically_inferred[parameter_index])
+    return result
+
+def _infer_returned(pyobject, args):
+    if args:
+        # HACK: Setting parameter objects manually
+        # This is not thread safe and might cause problems if `args`
+        # does not come from a good call site
+        pyobject.get_scope().invalidate_data()
+        pyobject._set_parameter_pyobjects(
+            args.get_arguments(pyobject.get_param_names(special_args=False)))
+    scope = pyobject.get_scope()
+    if not scope._get_returned_asts():
+        return
+    maxtries = 3
+    for returned_node in reversed(scope._get_returned_asts()[-maxtries:]):
+        try:
+            resulting_pyname = evaluate.eval_node(scope, returned_node)
+            if resulting_pyname is None:
+                continue
+            pyobject = resulting_pyname.get_object()
+            if pyobject == rope.base.pyobjects.get_unknown():
+                continue
+            if not scope._is_generator():
+                return pyobject
+            else:
+                return rope.base.builtins.get_generator(pyobject)
+        except rope.base.pyobjects.IsBeingInferredError:
+            pass
+
+def _parameter_objects(pyobject):
+    params = pyobject.get_param_names(special_args=False)
+    return [rope.base.pyobjects.get_unknown()] * len(params)
+
+# handling `rope.base.pynames.AssignmentValue`
+
+@_ignore_inferred
+def _infer_assignment(assignment, pymodule):
+    result = _follow_pyname(assignment, pymodule)
+    if result is None:
+        return None
+    pyname, pyobject = result
+    pyobject = _follow_evaluations(assignment, pyname, pyobject)
+    if pyobject is None:
+        return None
+    return _follow_levels(assignment, pyobject)
+
+def _follow_levels(assignment, pyobject):
+    for index in assignment.levels:
+        if isinstance(pyobject.get_type(), rope.base.builtins.Tuple):
+            holdings = pyobject.get_type().get_holding_objects()
+            if holdings:
+                pyobject = holdings[min(len(holdings) - 1, index)]
+            else:
+                pyobject = None
+        elif isinstance(pyobject.get_type(), rope.base.builtins.List):
+            pyobject = pyobject.get_type().holding
+        else:
+            pyobject = None
+        if pyobject is None:
+            break
+    return pyobject
+
+@_ignore_inferred
+def _follow_pyname(assignment, pymodule, lineno=None):
+    assign_node = assignment.ast_node
+    if lineno is None:
+        lineno = _get_lineno_for_node(assign_node)
+    holding_scope = pymodule.get_scope().get_inner_scope_for_line(lineno)
+    pyname = evaluate.eval_node(holding_scope, assign_node)
+    if pyname is not None:
+        result = pyname.get_object()
+        if isinstance(result.get_type(), rope.base.builtins.Property) and \
+           holding_scope.get_kind() == 'Class':
+            arg = rope.base.pynames.UnboundName(
+                rope.base.pyobjects.PyObject(holding_scope.pyobject))
+            return pyname, result.get_type().get_property_object(
+                arguments.ObjectArguments([arg]))
+        return pyname, result
+
+@_ignore_inferred
+def _follow_evaluations(assignment, pyname, pyobject):
+    new_pyname = pyname
+    tokens = assignment.evaluation.split('.')
+    for token in tokens:
+        call = token.endswith('()')
+        if call:
+            token = token[:-2]
+        if token:
+            pyname = new_pyname
+            new_pyname = _get_attribute(pyobject, token)
+            if new_pyname is not None:
+                pyobject = new_pyname.get_object()
+        if pyobject is not None and call:
+            if isinstance(pyobject, rope.base.pyobjects.AbstractFunction):
+                args = arguments.ObjectArguments([pyname])
+                pyobject = pyobject.get_returned_object(args)
+            else:
+                pyobject = None
+        if pyobject is None:
+            break
+    if pyobject is not None and assignment.assign_type:
+        return rope.base.pyobjects.PyObject(pyobject)
+    return pyobject
+
+
+def _get_lineno_for_node(assign_node):
+    if hasattr(assign_node, 'lineno') and \
+       assign_node.lineno is not None:
+        return assign_node.lineno
+    return 1
+
+def _get_attribute(pyobject, name):
+    if pyobject is not None and name in pyobject:
+        return pyobject[name]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/oi/transform.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,285 @@
+"""Provides classes for persisting `PyObject`\s"""
+import os
+import re
+
+import rope.base.builtins
+from rope.base import exceptions
+
+
+class PyObjectToTextual(object):
+    """For transforming `PyObject` to textual form
+
+    This can be used for storing `PyObjects` in files.  Use
+    `TextualToPyObject` for converting back.
+
+    """
+
+    def __init__(self, project):
+        self.project = project
+
+    def transform(self, pyobject):
+        """Transform a `PyObject` to textual form"""
+        if pyobject is None:
+            return ('none',)
+        object_type = type(pyobject)
+        try:
+            method = getattr(self, object_type.__name__ + '_to_textual')
+            return method(pyobject)
+        except AttributeError:
+            return ('unknown',)
+
+    def __call__(self, pyobject):
+        return self.transform(pyobject)
+
+    def PyObject_to_textual(self, pyobject):
+        if isinstance(pyobject.get_type(), rope.base.pyobjects.AbstractClass):
+            result = self.transform(pyobject.get_type())
+            if result[0] == 'defined':
+                return ('instance', result)
+            return result
+        return ('unknown',)
+
+    def PyFunction_to_textual(self, pyobject):
+        return self._defined_to_textual(pyobject)
+
+    def PyClass_to_textual(self, pyobject):
+        return self._defined_to_textual(pyobject)
+
+    def _defined_to_textual(self, pyobject):
+        address = []
+        while pyobject.parent is not None:
+            address.insert(0, pyobject.get_name())
+            pyobject = pyobject.parent
+        return ('defined', self._get_pymodule_path(pyobject.get_module()),
+                '.'.join(address))
+
+    def PyModule_to_textual(self, pyobject):
+        return ('defined', self._get_pymodule_path(pyobject))
+
+    def PyPackage_to_textual(self, pyobject):
+        return ('defined', self._get_pymodule_path(pyobject))
+
+    def List_to_textual(self, pyobject):
+        return ('builtin', 'list', self.transform(pyobject.holding))
+
+    def Dict_to_textual(self, pyobject):
+        return ('builtin', 'dict', self.transform(pyobject.keys),
+                self.transform(pyobject.values))
+
+    def Tuple_to_textual(self, pyobject):
+        objects = [self.transform(holding)
+                   for holding in pyobject.get_holding_objects()]
+        return tuple(['builtin', 'tuple'] + objects)
+
+    def Set_to_textual(self, pyobject):
+        return ('builtin', 'set', self.transform(pyobject.holding))
+
+    def Iterator_to_textual(self, pyobject):
+        return ('builtin', 'iter', self.transform(pyobject.holding))
+
+    def Generator_to_textual(self, pyobject):
+        return ('builtin', 'generator', self.transform(pyobject.holding))
+
+    def Str_to_textual(self, pyobject):
+        return ('builtin', 'str')
+
+    def File_to_textual(self, pyobject):
+        return ('builtin', 'file')
+
+    def BuiltinFunction_to_textual(self, pyobject):
+        return ('builtin', 'function', pyobject.get_name())
+
+    def _get_pymodule_path(self, pymodule):
+        return self.resource_to_path(pymodule.get_resource())
+
+    def resource_to_path(self, resource):
+        if resource.project == self.project:
+            return resource.path
+        else:
+            return resource.real_path
+
+
+class TextualToPyObject(object):
+    """For transforming textual form to `PyObject`"""
+
+    def __init__(self, project, allow_in_project_absolutes=False):
+        self.project = project
+
+    def __call__(self, textual):
+        return self.transform(textual)
+
+    def transform(self, textual):
+        """Transform an object from textual form to `PyObject`"""
+        if textual is None:
+            return None
+        type = textual[0]
+        try:
+            method = getattr(self, type + '_to_pyobject')
+            return method(textual)
+        except AttributeError:
+            return None
+
+    def builtin_to_pyobject(self, textual):
+        name = textual[1]
+        method = getattr(self, 'builtin_%s_to_pyobject' % textual[1], None)
+        if method is not None:
+            return method(textual)
+
+    def builtin_str_to_pyobject(self, textual):
+        return rope.base.builtins.get_str()
+
+    def builtin_list_to_pyobject(self, textual):
+        holding = self.transform(textual[2])
+        return rope.base.builtins.get_list(holding)
+
+    def builtin_dict_to_pyobject(self, textual):
+        keys = self.transform(textual[2])
+        values = self.transform(textual[3])
+        return rope.base.builtins.get_dict(keys, values)
+
+    def builtin_tuple_to_pyobject(self, textual):
+        objects = []
+        for holding in textual[2:]:
+            objects.append(self.transform(holding))
+        return rope.base.builtins.get_tuple(*objects)
+
+    def builtin_set_to_pyobject(self, textual):
+        holding = self.transform(textual[2])
+        return rope.base.builtins.get_set(holding)
+
+    def builtin_iter_to_pyobject(self, textual):
+        holding = self.transform(textual[2])
+        return rope.base.builtins.get_iterator(holding)
+
+    def builtin_generator_to_pyobject(self, textual):
+        holding = self.transform(textual[2])
+        return rope.base.builtins.get_generator(holding)
+
+    def builtin_file_to_pyobject(self, textual):
+        return rope.base.builtins.get_file()
+
+    def builtin_function_to_pyobject(self, textual):
+        if textual[2] in rope.base.builtins.builtins:
+            return rope.base.builtins.builtins[textual[2]].get_object()
+
+    def unknown_to_pyobject(self, textual):
+        return None
+
+    def none_to_pyobject(self, textual):
+        return None
+
+    def _module_to_pyobject(self, textual):
+        path = textual[1]
+        return self._get_pymodule(path)
+
+    def _hierarchical_defined_to_pyobject(self, textual):
+        path = textual[1]
+        names = textual[2].split('.')
+        pymodule = self._get_pymodule(path)
+        pyobject = pymodule
+        for name in names:
+            if pyobject is None:
+                return None
+            if isinstance(pyobject, rope.base.pyobjects.PyDefinedObject):
+                try:
+                    pyobject = pyobject.get_scope()[name].get_object()
+                except exceptions.NameNotFoundError:
+                    return None
+            else:
+                return None
+        return pyobject
+
+    def defined_to_pyobject(self, textual):
+        if len(textual) == 2 or textual[2] == '':
+            return self._module_to_pyobject(textual)
+        else:
+            return self._hierarchical_defined_to_pyobject(textual)
+
+    def instance_to_pyobject(self, textual):
+        type = self.transform(textual[1])
+        if type is not None:
+            return rope.base.pyobjects.PyObject(type)
+
+    def _get_pymodule(self, path):
+        resource = self.path_to_resource(path)
+        if resource is not None:
+            return self.project.pycore.resource_to_pyobject(resource)
+
+    def path_to_resource(self, path):
+        try:
+            root = self.project.address
+            if not os.path.isabs(path):
+                return self.project.get_resource(path)
+            if path == root or path.startswith(root + os.sep):
+                # INFO: This is a project file; should not be absolute
+                return None
+            import rope.base.project
+            return rope.base.project.get_no_project().get_resource(path)
+        except exceptions.ResourceNotFoundError:
+            return None
+
+
+class DOITextualToPyObject(TextualToPyObject):
+    """For transforming textual form to `PyObject`
+    
+    The textual form DOI uses is different from rope's standard
+    textual form.  The reason is that we cannot find the needed
+    information by analyzing live objects.  This class can be
+    used to transform DOI textual form to `PyObject` and later
+    we can convert it to standard textual form using
+    `TextualToPyObject` class.
+
+    """
+
+    def _function_to_pyobject(self, textual):
+        path = textual[1]
+        lineno = int(textual[2])
+        pymodule = self._get_pymodule(path)
+        if pymodule is not None:
+            scope = pymodule.get_scope()
+            inner_scope = scope.get_inner_scope_for_line(lineno)
+            return inner_scope.pyobject
+
+    def _class_to_pyobject(self, textual):
+        path, name = textual[1:]
+        pymodule = self._get_pymodule(path)
+        if pymodule is None:
+            return None
+        module_scope = pymodule.get_scope()
+        suspected = None
+        if name in module_scope.get_names():
+            suspected = module_scope[name].get_object()
+        if suspected is not None and \
+           isinstance(suspected, rope.base.pyobjects.PyClass):
+            return suspected
+        else:
+            lineno = self._find_occurrence(name, pymodule.get_resource().read())
+            if lineno is not None:
+                inner_scope = module_scope.get_inner_scope_for_line(lineno)
+                return inner_scope.pyobject
+
+    def defined_to_pyobject(self, textual):
+        if len(textual) == 2:
+            return self._module_to_pyobject(textual)
+        else:
+            if textual[2].isdigit():
+                result = self._function_to_pyobject(textual)
+            else:
+                result = self._class_to_pyobject(textual)
+            if not isinstance(result, rope.base.pyobjects.PyModule):
+                return result
+
+    def _find_occurrence(self, name, source):
+        pattern = re.compile(r'^\s*class\s*' + name + r'\b')
+        lines = source.split('\n')
+        for i in range(len(lines)):
+            if pattern.match(lines[i]):
+                return i + 1
+
+    def path_to_resource(self, path):
+        import rope.base.libutils
+        root = self.project.address
+        relpath = rope.base.libutils.relative(root, path)
+        if relpath is not None:
+            path = relpath
+        return super(DOITextualToPyObject, self).path_to_resource(path)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/prefs.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,41 @@
+class Prefs(object):
+
+    def __init__(self):
+        self.prefs = {}
+        self.callbacks = {}
+
+    def set(self, key, value):
+        """Set the value of `key` preference to `value`."""
+        if key in self.callbacks:
+            self.callbacks[key](value)
+        else:
+            self.prefs[key] = value
+
+    def add(self, key, value):
+        """Add an entry to a list preference
+
+        Add `value` to the list of entries for the `key` preference.
+
+        """
+        if not key in self.prefs:
+            self.prefs[key] = []
+        self.prefs[key].append(value)
+
+    def get(self, key, default=None):
+        """Get the value of the key preference"""
+        return self.prefs.get(key, default)
+
+    def add_callback(self, key, callback):
+        """Add `key` preference with `callback` function
+        
+        Whenever `key` is set the callback is called with the
+        given `value` as parameter.
+
+        """
+        self.callbacks[key] = callback
+
+    def __setitem__(self, key, value):
+        self.set(key, value)
+
+    def __getitem__(self, key):
+        return self.get(key)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/project.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,375 @@
+import cPickle as pickle
+import os
+import shutil
+import sys
+import warnings
+
+import rope.base.fscommands
+from rope.base import exceptions, taskhandle, prefs, history, pycore, utils
+from rope.base.resourceobserver import *
+from rope.base.resources import File, Folder, _ResourceMatcher
+
+
+class _Project(object):
+
+    def __init__(self, fscommands):
+        self.observers = []
+        self.fscommands = fscommands
+        self.prefs = prefs.Prefs()
+        self.data_files = _DataFiles(self)
+
+    def get_resource(self, resource_name):
+        """Get a resource in a project.
+
+        `resource_name` is the path of a resource in a project.  It is
+        the path of a resource relative to project root.  Project root
+        folder address is an empty string.  If the resource does not
+        exist a `exceptions.ResourceNotFound` exception would be
+        raised.  Use `get_file()` and `get_folder()` when you need to
+        get nonexistent `Resource`\s.
+
+        """
+        path = self._get_resource_path(resource_name)
+        if not os.path.exists(path):
+            raise exceptions.ResourceNotFoundError(
+                'Resource <%s> does not exist' % resource_name)
+        elif os.path.isfile(path):
+            return File(self, resource_name)
+        elif os.path.isdir(path):
+            return Folder(self, resource_name)
+        else:
+            raise exceptions.ResourceNotFoundError('Unknown resource '
+                                                   + resource_name)
+
+    def validate(self, folder):
+        """Validate files and folders contained in this folder
+
+        It validates all of the files and folders contained in this
+        folder if some observers are interested in them.
+
+        """
+        for observer in list(self.observers):
+            observer.validate(folder)
+
+    def add_observer(self, observer):
+        """Register a `ResourceObserver`
+
+        See `FilteredResourceObserver`.
+        """
+        self.observers.append(observer)
+
+    def remove_observer(self, observer):
+        """Remove a registered `ResourceObserver`"""
+        if observer in self.observers:
+            self.observers.remove(observer)
+
+    def do(self, changes, task_handle=taskhandle.NullTaskHandle()):
+        """Apply the changes in a `ChangeSet`
+
+        Most of the time you call this function for committing the
+        changes for a refactoring.
+        """
+        self.history.do(changes, task_handle=task_handle)
+
+    def get_pycore(self):
+        return self.pycore
+
+    def get_file(self, path):
+        """Get the file with `path` (it may not exist)"""
+        return File(self, path)
+
+    def get_folder(self, path):
+        """Get the folder with `path` (it may not exist)"""
+        return Folder(self, path)
+
+    def is_ignored(self, resource):
+        return False
+
+    def get_prefs(self):
+        return self.prefs
+
+    def _get_resource_path(self, name):
+        pass
+
+    @property
+    @utils.saveit
+    def history(self):
+        return history.History(self)
+
+    @property
+    @utils.saveit
+    def pycore(self):
+        return pycore.PyCore(self)
+
+    def close(self):
+        warnings.warn('Cannot close a NoProject',
+                      DeprecationWarning, stacklevel=2)
+
+    ropefolder = None
+
+
+class Project(_Project):
+    """A Project containing files and folders"""
+
+    def __init__(self, projectroot, fscommands=None,
+                 ropefolder='.ropeproject', **prefs):
+        """A rope project
+
+        :parameters:
+            - `projectroot`: The address of the root folder of the project
+            - `fscommands`: Implements the file system operations used
+              by rope; have a look at `rope.base.fscommands`
+            - `ropefolder`: The name of the folder in which rope stores
+              project configurations and data.  Pass `None` for not using
+              such a folder at all.
+            - `prefs`: Specify project preferences.  These values
+              overwrite config file preferences.
+
+        """
+        if projectroot != '/':
+            projectroot = _realpath(projectroot).rstrip('/\\')
+        self._address = projectroot
+        self._ropefolder_name = ropefolder
+        if not os.path.exists(self._address):
+            os.mkdir(self._address)
+        elif not os.path.isdir(self._address):
+            raise exceptions.RopeError('Project root exists and'
+                                       ' is not a directory')
+        if fscommands is None:
+            fscommands = rope.base.fscommands.create_fscommands(self._address)
+        super(Project, self).__init__(fscommands)
+        self.ignored = _ResourceMatcher()
+        self.file_list = _FileListCacher(self)
+        self.prefs.add_callback('ignored_resources', self.ignored.set_patterns)
+        if ropefolder is not None:
+            self.prefs['ignored_resources'] = [ropefolder]
+        self._init_prefs(prefs)
+
+    def get_files(self):
+        return self.file_list.get_files()
+
+    def _get_resource_path(self, name):
+        return os.path.join(self._address, *name.split('/'))
+
+    def _init_ropefolder(self):
+        if self.ropefolder is not None:
+            if not self.ropefolder.exists():
+                self._create_recursively(self.ropefolder)
+            if not self.ropefolder.has_child('config.py'):
+                config = self.ropefolder.create_file('config.py')
+                config.write(self._default_config())
+
+    def _create_recursively(self, folder):
+        if folder.parent != self.root and not folder.parent.exists():
+            self._create_recursively(folder.parent)
+        folder.create()
+
+    def _init_prefs(self, prefs):
+        run_globals = {}
+        if self.ropefolder is not None:
+            config = self.get_file(self.ropefolder.path + '/config.py')
+            run_globals.update({'__name__': '__main__',
+                                '__builtins__': __builtins__,
+                                '__file__': config.real_path})
+            if config.exists():
+                config = self.ropefolder.get_child('config.py')
+                execfile(config.real_path, run_globals)
+            else:
+                exec(self._default_config(), run_globals)
+            if 'set_prefs' in run_globals:
+                run_globals['set_prefs'](self.prefs)
+        for key, value in prefs.items():
+            self.prefs[key] = value
+        self._init_other_parts()
+        self._init_ropefolder()
+        if 'project_opened' in run_globals:
+            run_globals['project_opened'](self)
+
+    def _default_config(self):
+        import rope.base.default_config
+        import inspect
+        return inspect.getsource(rope.base.default_config)
+
+    def _init_other_parts(self):
+        # Forcing the creation of `self.pycore` to register observers
+        self.pycore
+
+    def is_ignored(self, resource):
+        return self.ignored.does_match(resource)
+
+    def sync(self):
+        """Closes project open resources"""
+        self.close()
+
+    def close(self):
+        """Closes project open resources"""
+        self.data_files.write()
+
+    def set(self, key, value):
+        """Set the `key` preference to `value`"""
+        self.prefs.set(key, value)
+
+    @property
+    def ropefolder(self):
+        if self._ropefolder_name is not None:
+            return self.get_folder(self._ropefolder_name)
+
+    def validate(self, folder=None):
+        if folder is None:
+            folder = self.root
+        super(Project, self).validate(folder)
+
+    root = property(lambda self: self.get_resource(''))
+    address = property(lambda self: self._address)
+
+
+class NoProject(_Project):
+    """A null object for holding out of project files.
+
+    This class is singleton use `get_no_project` global function
+    """
+
+    def __init__(self):
+        fscommands = rope.base.fscommands.FileSystemCommands()
+        super(NoProject, self).__init__(fscommands)
+
+    def _get_resource_path(self, name):
+        real_name = name.replace('/', os.path.sep)
+        return _realpath(real_name)
+
+    def get_resource(self, name):
+        universal_name = _realpath(name).replace(os.path.sep, '/')
+        return super(NoProject, self).get_resource(universal_name)
+
+    def get_files(self):
+        return []
+
+    _no_project = None
+
+
+def get_no_project():
+    if NoProject._no_project is None:
+        NoProject._no_project = NoProject()
+    return NoProject._no_project
+
+
+class _FileListCacher(object):
+
+    def __init__(self, project):
+        self.project = project
+        self.files = None
+        rawobserver = ResourceObserver(
+            self._changed, self._invalid, self._invalid,
+            self._invalid, self._invalid)
+        self.project.add_observer(rawobserver)
+
+    def get_files(self):
+        if self.files is None:
+            self.files = set()
+            self._add_files(self.project.root)
+        return self.files
+
+    def _add_files(self, folder):
+        for child in folder.get_children():
+            if child.is_folder():
+                self._add_files(child)
+            elif not self.project.is_ignored(child):
+                self.files.add(child)
+
+    def _changed(self, resource):
+        if resource.is_folder():
+            self.files = None
+
+    def _invalid(self, resource, new_resource=None):
+        self.files = None
+
+
+class _DataFiles(object):
+
+    def __init__(self, project):
+        self.project = project
+        self.hooks = []
+
+    def read_data(self, name, compress=False, import_=False):
+        if self.project.ropefolder is None:
+            return None
+        compress = compress and self._can_compress()
+        opener = self._get_opener(compress)
+        file = self._get_file(name, compress)
+        if not compress and import_:
+            self._import_old_files(name)
+        if file.exists():
+            input = opener(file.real_path, 'rb')
+            try:
+                result = []
+                try:
+                    while True:
+                        result.append(pickle.load(input))
+                except EOFError:
+                    pass
+                if len(result) == 1:
+                    return result[0]
+                if len(result) > 1:
+                    return result
+            finally:
+                input.close()
+
+    def write_data(self, name, data, compress=False):
+        if self.project.ropefolder is not None:
+            compress = compress and self._can_compress()
+            file = self._get_file(name, compress)
+            opener = self._get_opener(compress)
+            output = opener(file.real_path, 'wb')
+            try:
+                pickle.dump(data, output, 2)
+            finally:
+                output.close()
+
+    def add_write_hook(self, hook):
+        self.hooks.append(hook)
+
+    def write(self):
+        for hook in self.hooks:
+            hook()
+
+    def _can_compress(self):
+        try:
+            import gzip
+            return True
+        except ImportError:
+            return False
+
+    def _import_old_files(self, name):
+        old = self._get_file(name + '.pickle', False)
+        new = self._get_file(name, False)
+        if old.exists() and not new.exists():
+            shutil.move(old.real_path, new.real_path)
+
+    def _get_opener(self, compress):
+        if compress:
+            try:
+                import gzip
+                return gzip.open
+            except ImportError:
+                pass
+        return open
+
+    def _get_file(self, name, compress):
+        path = self.project.ropefolder.path + '/' + name
+        if compress:
+            path += '.gz'
+        return self.project.get_file(path)
+
+
+def _realpath(path):
+    """Return the real path of `path`
+
+    Is equivalent to ``realpath(abspath(expanduser(path)))``.
+
+    """
+    # there is a bug in cygwin for os.path.abspath() for abs paths
+    if sys.platform == 'cygwin':
+        if path[1:3] == ':\\':
+            return path
+        return os.path.abspath(os.path.expanduser(path))
+    return os.path.realpath(os.path.abspath(os.path.expanduser(path)))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/pycore.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,409 @@
+import bisect
+import difflib
+import sys
+import warnings
+
+import rope.base.oi.doa
+import rope.base.oi.objectinfo
+import rope.base.oi.soa
+from rope.base import ast, exceptions, taskhandle, utils, stdmods
+from rope.base.exceptions import ModuleNotFoundError
+from rope.base.pyobjectsdef import PyModule, PyPackage, PyClass
+import rope.base.resources
+import rope.base.resourceobserver
+from rope.base import builtins
+
+
+class PyCore(object):
+
+    def __init__(self, project):
+        self.project = project
+        self._init_resource_observer()
+        self.cache_observers = []
+        self.module_cache = _ModuleCache(self)
+        self.extension_cache = _ExtensionCache(self)
+        self.object_info = rope.base.oi.objectinfo.ObjectInfoManager(project)
+        self._init_python_files()
+        self._init_automatic_soa()
+        self._init_source_folders()
+
+    def _init_python_files(self):
+        self.python_matcher = None
+        patterns = self.project.prefs.get('python_files', None)
+        if patterns is not None:
+            self.python_matcher = rope.base.resources._ResourceMatcher()
+            self.python_matcher.set_patterns(patterns)
+
+    def _init_resource_observer(self):
+        callback = self._invalidate_resource_cache
+        observer = rope.base.resourceobserver.ResourceObserver(
+            changed=callback, moved=callback, removed=callback)
+        self.observer = rope.base.resourceobserver.FilteredResourceObserver(observer)
+        self.project.add_observer(self.observer)
+
+    def _init_source_folders(self):
+        self._custom_source_folders = []
+        for path in self.project.prefs.get('source_folders', []):
+            folder = self.project.get_resource(path)
+            self._custom_source_folders.append(folder)
+
+    def _init_automatic_soa(self):
+        if not self.automatic_soa:
+            return
+        callback = self._file_changed_for_soa
+        observer = rope.base.resourceobserver.ResourceObserver(
+            changed=callback, moved=callback, removed=callback)
+        self.project.add_observer(observer)
+
+    @property
+    def automatic_soa(self):
+        auto_soa = self.project.prefs.get('automatic_soi', None)
+        return self.project.prefs.get('automatic_soa', auto_soa)
+
+    def _file_changed_for_soa(self, resource, new_resource=None):
+        old_contents = self.project.history.\
+                       contents_before_current_change(resource)
+        if old_contents is not None:
+            perform_soa_on_changed_scopes(self.project, resource, old_contents)
+
+    def is_python_file(self, resource):
+        if resource.is_folder():
+            return False
+        if self.python_matcher is None:
+            return resource.name.endswith('.py')
+        return self.python_matcher.does_match(resource)
+
+    def get_module(self, name, folder=None):
+        """Returns a `PyObject` if the module was found."""
+        module = self.find_module(name, folder)
+        if module is None:
+            module = self._builtin_module(name)
+            if module is None:
+                raise ModuleNotFoundError('Module %s not found' % name)
+            return module
+        return self.resource_to_pyobject(module)
+
+    def _builtin_submodules(self, modname):
+        result = {}
+        for extension in self.extension_modules:
+            if extension.startswith(modname + '.'):
+                name = extension[len(modname) + 1:]
+                if '.' not in name:
+                    result[name] = self._builtin_module(extension)
+        return result
+
+    def _builtin_module(self, name):
+        return self.extension_cache.get_pymodule(name)
+
+    def get_relative_module(self, name, folder, level):
+        module = self.find_relative_module(name, folder, level)
+        if module is None:
+            raise ModuleNotFoundError('Module %s not found' % name)
+        return self.resource_to_pyobject(module)
+
+    def get_string_module(self, code, resource=None, force_errors=False):
+        """Returns a `PyObject` object for the given code
+
+        If `force_errors` is `True`, `exceptions.ModuleSyntaxError` is
+        raised if module has syntax errors.  This overrides
+        ``ignore_syntax_errors`` project config.
+
+        """
+        return PyModule(self, code, resource, force_errors=force_errors)
+
+    def get_string_scope(self, code, resource=None):
+        """Returns a `Scope` object for the given code"""
+        return self.get_string_module(code, resource).get_scope()
+
+    def _invalidate_resource_cache(self, resource, new_resource=None):
+        for observer in self.cache_observers:
+            observer(resource)
+
+    def _find_module_in_folder(self, folder, modname):
+        module = folder
+        packages = modname.split('.')
+        for pkg in packages[:-1]:
+            if  module.is_folder() and module.has_child(pkg):
+                module = module.get_child(pkg)
+            else:
+                return None
+        if module.is_folder():
+            if module.has_child(packages[-1]) and \
+               module.get_child(packages[-1]).is_folder():
+                return module.get_child(packages[-1])
+            elif module.has_child(packages[-1] + '.py') and \
+                 not module.get_child(packages[-1] + '.py').is_folder():
+                return module.get_child(packages[-1] + '.py')
+
+    def get_python_path_folders(self):
+        import rope.base.project
+        result = []
+        for src in self.project.prefs.get('python_path', []) + sys.path:
+            try:
+                src_folder = rope.base.project.get_no_project().get_resource(src)
+                result.append(src_folder)
+            except rope.base.exceptions.ResourceNotFoundError:
+                pass
+        return result
+
+    def find_module(self, modname, folder=None):
+        """Returns a resource corresponding to the given module
+
+        returns None if it can not be found
+        """
+        return self._find_module(modname, folder)
+
+    def find_relative_module(self, modname, folder, level):
+        for i in range(level - 1):
+            folder = folder.parent
+        if modname == '':
+            return folder
+        else:
+            return self._find_module_in_folder(folder, modname)
+
+    def _find_module(self, modname, folder=None):
+        """Return `modname` module resource"""
+        for src in self.get_source_folders():
+            module = self._find_module_in_folder(src, modname)
+            if module is not None:
+                return module
+        for src in self.get_python_path_folders():
+            module = self._find_module_in_folder(src, modname)
+            if module is not None:
+                return module
+        if folder is not None:
+            module = self._find_module_in_folder(folder, modname)
+            if module is not None:
+                return module
+        return None
+
+    # INFO: It was decided not to cache source folders, since:
+    #  - Does not take much time when the root folder contains
+    #    packages, that is most of the time
+    #  - We need a separate resource observer; `self.observer`
+    #    does not get notified about module and folder creations
+    def get_source_folders(self):
+        """Returns project source folders"""
+        if self.project.root is None:
+            return []
+        result = list(self._custom_source_folders)
+        result.extend(self._find_source_folders(self.project.root))
+        return result
+
+    def resource_to_pyobject(self, resource, force_errors=False):
+        return self.module_cache.get_pymodule(resource, force_errors)
+
+    def get_python_files(self):
+        """Returns all python files available in the project"""
+        return [resource for resource in self.project.get_files()
+                if self.is_python_file(resource)]
+
+    def _is_package(self, folder):
+        if folder.has_child('__init__.py') and \
+           not folder.get_child('__init__.py').is_folder():
+            return True
+        else:
+            return False
+
+    def _find_source_folders(self, folder):
+        for resource in folder.get_folders():
+            if self._is_package(resource):
+                return [folder]
+        result = []
+        for resource in folder.get_files():
+            if resource.name.endswith('.py'):
+                result.append(folder)
+                break
+        for resource in folder.get_folders():
+            result.extend(self._find_source_folders(resource))
+        return result
+
+    def run_module(self, resource, args=None, stdin=None, stdout=None):
+        """Run `resource` module
+
+        Returns a `rope.base.oi.doa.PythonFileRunner` object for
+        controlling the process.
+
+        """
+        perform_doa = self.project.prefs.get('perform_doi', True)
+        perform_doa = self.project.prefs.get('perform_doa', perform_doa)
+        receiver = self.object_info.doa_data_received
+        if not perform_doa:
+            receiver = None
+        runner = rope.base.oi.doa.PythonFileRunner(
+            self, resource, args, stdin, stdout, receiver)
+        runner.add_finishing_observer(self.module_cache.forget_all_data)
+        runner.run()
+        return runner
+
+    def analyze_module(self, resource, should_analyze=lambda py: True,
+                       search_subscopes=lambda py: True, followed_calls=None):
+        """Analyze `resource` module for static object inference
+
+        This function forces rope to analyze this module to collect
+        information about function calls.  `should_analyze` is a
+        function that is called with a `PyDefinedObject` argument.  If
+        it returns `True` the element is analyzed.  If it is `None` or
+        returns `False` the element is not analyzed.
+
+        `search_subscopes` is like `should_analyze`; The difference is
+        that if it returns `False` the sub-scopes are all ignored.
+        That is it is assumed that `should_analyze` returns `False`
+        for all of its subscopes.
+
+        `followed_calls` override the value of ``soa_followed_calls``
+        project config.
+        """
+        if followed_calls is None:
+            followed_calls = self.project.prefs.get('soa_followed_calls', 0)
+        pymodule = self.resource_to_pyobject(resource)
+        self.module_cache.forget_all_data()
+        rope.base.oi.soa.analyze_module(
+            self, pymodule, should_analyze, search_subscopes, followed_calls)
+
+    def get_classes(self, task_handle=taskhandle.NullTaskHandle()):
+        warnings.warn('`PyCore.get_classes()` is deprecated',
+                      DeprecationWarning, stacklevel=2)
+        return []
+
+    def __str__(self):
+        return str(self.module_cache) + str(self.object_info)
+
+    def modname(self, resource):
+        if resource.is_folder():
+            module_name = resource.name
+            source_folder = resource.parent
+        elif resource.name == '__init__.py':
+            module_name = resource.parent.name
+            source_folder = resource.parent.parent
+        else:
+            module_name = resource.name[:-3]
+            source_folder = resource.parent
+
+        while source_folder != source_folder.parent and \
+              source_folder.has_child('__init__.py'):
+            module_name = source_folder.name + '.' + module_name
+            source_folder = source_folder.parent
+        return module_name
+
+    @property
+    @utils.cacheit
+    def extension_modules(self):
+        result = set(self.project.prefs.get('extension_modules', []))
+        if self.project.prefs.get('import_dynload_stdmods', False):
+            result.update(stdmods.dynload_modules())
+        return result
+
+
+class _ModuleCache(object):
+
+    def __init__(self, pycore):
+        self.pycore = pycore
+        self.module_map = {}
+        self.pycore.cache_observers.append(self._invalidate_resource)
+        self.observer = self.pycore.observer
+
+    def _invalidate_resource(self, resource):
+        if resource in self.module_map:
+            self.forget_all_data()
+            self.observer.remove_resource(resource)
+            del self.module_map[resource]
+
+    def get_pymodule(self, resource, force_errors=False):
+        if resource in self.module_map:
+            return self.module_map[resource]
+        if resource.is_folder():
+            result = PyPackage(self.pycore, resource,
+                               force_errors=force_errors)
+        else:
+            result = PyModule(self.pycore, resource=resource,
+                              force_errors=force_errors)
+            if result.has_errors:
+                return result
+        self.module_map[resource] = result
+        self.observer.add_resource(resource)
+        return result
+
+    def forget_all_data(self):
+        for pymodule in self.module_map.values():
+            pymodule._forget_concluded_data()
+
+    def __str__(self):
+        return 'PyCore caches %d PyModules\n' % len(self.module_map)
+
+
+class _ExtensionCache(object):
+
+    def __init__(self, pycore):
+        self.pycore = pycore
+        self.extensions = {}
+
+    def get_pymodule(self, name):
+        if name == '__builtin__':
+            return builtins.builtins
+        allowed = self.pycore.extension_modules
+        if name not in self.extensions and name in allowed:
+            self.extensions[name] = builtins.BuiltinModule(name, self.pycore)
+        return self.extensions.get(name)
+
+
+def perform_soa_on_changed_scopes(project, resource, old_contents):
+    pycore = project.pycore
+    if resource.exists() and pycore.is_python_file(resource):
+        try:
+            new_contents = resource.read()
+            # detecting changes in new_contents relative to old_contents
+            detector = _TextChangeDetector(new_contents, old_contents)
+            def search_subscopes(pydefined):
+                scope = pydefined.get_scope()
+                return detector.is_changed(scope.get_start(), scope.get_end())
+            def should_analyze(pydefined):
+                scope = pydefined.get_scope()
+                start = scope.get_start()
+                end = scope.get_end()
+                return detector.consume_changes(start, end)
+            pycore.analyze_module(resource, should_analyze, search_subscopes)
+        except exceptions.ModuleSyntaxError:
+            pass
+
+
+class _TextChangeDetector(object):
+
+    def __init__(self, old, new):
+        self.old = old
+        self.new = new
+        self._set_diffs()
+
+    def _set_diffs(self):
+        differ = difflib.Differ()
+        self.lines = []
+        lineno = 0
+        for line in differ.compare(self.old.splitlines(True),
+                                   self.new.splitlines(True)):
+            if line.startswith(' '):
+                lineno += 1
+            elif line.startswith('-'):
+                lineno += 1
+                self.lines.append(lineno)
+
+    def is_changed(self, start, end):
+        """Tell whether any of start till end lines have changed
+
+        The end points are inclusive and indices start from 1.
+        """
+        left, right = self._get_changed(start, end)
+        if left < right:
+            return True
+        return False
+
+    def consume_changes(self, start, end):
+        """Clear the changed status of lines from start till end"""
+        left, right = self._get_changed(start, end)
+        if left < right:
+            del self.lines[left:right]
+        return left < right
+
+    def _get_changed(self, start, end):
+        left = bisect.bisect_left(self.lines, start)
+        right = bisect.bisect_right(self.lines, end)
+        return left, right
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/pynames.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,199 @@
+import rope.base.pyobjects
+from rope.base import exceptions, utils
+
+
+class PyName(object):
+    """References to `PyObject`\s inside python programs"""
+
+    def get_object(self):
+        """Return the `PyObject` object referenced by this `PyName`"""
+
+    def get_definition_location(self):
+        """Return a (module, lineno) tuple"""
+
+
+class DefinedName(PyName):
+
+    def __init__(self, pyobject):
+        self.pyobject = pyobject
+
+    def get_object(self):
+        return self.pyobject
+
+    def get_definition_location(self):
+        return (self.pyobject.get_module(), self.pyobject.get_ast().lineno)
+
+
+class AssignedName(PyName):
+    """Only a placeholder"""
+
+
+class UnboundName(PyName):
+
+    def __init__(self, pyobject=None):
+        self.pyobject = pyobject
+        if self.pyobject is None:
+            self.pyobject = rope.base.pyobjects.get_unknown()
+
+    def get_object(self):
+        return self.pyobject
+
+    def get_definition_location(self):
+        return (None, None)
+
+
+class AssignmentValue(object):
+    """An assigned expression"""
+
+    def __init__(self, ast_node, levels=None, evaluation='',
+                 assign_type=False):
+        """The `level` is `None` for simple assignments and is
+        a list of numbers for tuple assignments for example in::
+
+           a, (b, c) = x
+
+        The levels for for `a` is ``[0]``, for `b` is ``[1, 0]`` and for
+        `c` is ``[1, 1]``.
+
+        """
+        self.ast_node = ast_node
+        if levels == None:
+            self.levels = []
+        else:
+            self.levels = levels
+        self.evaluation = evaluation
+        self.assign_type = assign_type
+
+    def get_lineno(self):
+        return self.ast_node.lineno
+
+
+class EvaluatedName(PyName):
+    """A name whose object will be evaluated later"""
+
+    def __init__(self, callback, module=None, lineno=None):
+        self.module = module
+        self.lineno = lineno
+        self.callback = callback
+        self.pyobject = _Inferred(callback, _get_concluded_data(module))
+
+    def get_object(self):
+        return self.pyobject.get()
+
+    def get_definition_location(self):
+        return (self.module, self.lineno)
+
+    def invalidate(self):
+        """Forget the `PyObject` this `PyName` holds"""
+        self.pyobject.set(None)
+
+
+class ParameterName(PyName):
+    """Only a placeholder"""
+
+
+class ImportedModule(PyName):
+
+    def __init__(self, importing_module, module_name=None,
+                 level=0, resource=None):
+        self.importing_module = importing_module
+        self.module_name = module_name
+        self.level = level
+        self.resource = resource
+        self.pymodule = _get_concluded_data(self.importing_module)
+
+    def _current_folder(self):
+        resource = self.importing_module.get_module().get_resource()
+        if resource is None:
+            return None
+        return resource.parent
+
+    def _get_pymodule(self):
+        if self.pymodule.get() is None:
+            pycore = self.importing_module.pycore
+            if self.resource is not None:
+                self.pymodule.set(pycore.resource_to_pyobject(self.resource))
+            elif self.module_name is not None:
+                try:
+                    if self.level == 0:
+                        pymodule = pycore.get_module(self.module_name,
+                                                     self._current_folder())
+                    else:
+                        pymodule = pycore.get_relative_module(
+                            self.module_name, self._current_folder(), self.level)
+                    self.pymodule.set(pymodule)
+                except exceptions.ModuleNotFoundError:
+                    pass
+        return self.pymodule.get()
+
+    def get_object(self):
+        if self._get_pymodule() is None:
+            return rope.base.pyobjects.get_unknown()
+        return self._get_pymodule()
+
+    def get_definition_location(self):
+        pymodule = self._get_pymodule()
+        if not isinstance(pymodule, rope.base.pyobjects.PyDefinedObject):
+            return (None, None)
+        return (pymodule.get_module(), 1)
+
+
+class ImportedName(PyName):
+
+    def __init__(self, imported_module, imported_name):
+        self.imported_module = imported_module
+        self.imported_name = imported_name
+
+    def _get_imported_pyname(self):
+        try:
+            result = self.imported_module.get_object()[self.imported_name]
+            if result != self:
+                return result
+        except exceptions.AttributeNotFoundError:
+            pass
+        return UnboundName()
+
+    @utils.prevent_recursion(rope.base.pyobjects.get_unknown)
+    def get_object(self):
+        return self._get_imported_pyname().get_object()
+
+    @utils.prevent_recursion(lambda: (None, None))
+    def get_definition_location(self):
+        return self._get_imported_pyname().get_definition_location()
+
+
+def _get_concluded_data(module):
+    if module is None:
+        return rope.base.pyobjects._ConcludedData()
+    return module._get_concluded_data()
+
+
+def _circular_inference():
+    raise rope.base.pyobjects.IsBeingInferredError(
+        'Circular Object Inference')
+
+class _Inferred(object):
+
+    def __init__(self, get_inferred, concluded=None):
+        self.get_inferred = get_inferred
+        self.concluded = concluded
+        if self.concluded is None:
+            self.temp = None
+
+    @utils.prevent_recursion(_circular_inference)
+    def get(self, *args, **kwds):
+        if self.concluded is None or self.concluded.get() is None:
+            self.set(self.get_inferred(*args, **kwds))
+        if self._get() is None:
+            self.set(rope.base.pyobjects.get_unknown())
+        return self._get()
+
+    def set(self, pyobject):
+        if self.concluded is not None:
+            self.concluded.set(pyobject)
+        self.temp = pyobject
+
+    def _get(self):
+        if self.concluded is not None:
+            return self.concluded.get()
+        return self.temp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/pynamesdef.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,55 @@
+import rope.base.oi.soi
+from rope.base import pynames
+from rope.base.pynames import *
+
+
+class AssignedName(pynames.AssignedName):
+
+    def __init__(self, lineno=None, module=None, pyobject=None):
+        self.lineno = lineno
+        self.module = module
+        self.assignments = []
+        self.pyobject = _Inferred(self._get_inferred,
+                                  pynames._get_concluded_data(module))
+        self.pyobject.set(pyobject)
+
+    @utils.prevent_recursion(lambda: None)
+    def _get_inferred(self):
+        if self.module is not None:
+            return rope.base.oi.soi.infer_assigned_object(self)
+
+    def get_object(self):
+        return self.pyobject.get()
+
+    def get_definition_location(self):
+        """Returns a (module, lineno) tuple"""
+        if self.lineno is None and self.assignments:
+            self.lineno = self.assignments[0].get_lineno()
+        return (self.module, self.lineno)
+
+    def invalidate(self):
+        """Forget the `PyObject` this `PyName` holds"""
+        self.pyobject.set(None)
+
+
+class ParameterName(pynames.ParameterName):
+
+    def __init__(self, pyfunction, index):
+        self.pyfunction = pyfunction
+        self.index = index
+
+    def get_object(self):
+        result = self.pyfunction.get_parameter(self.index)
+        if result is None:
+            result = rope.base.pyobjects.get_unknown()
+        return result
+
+    def get_objects(self):
+        """Returns the list of objects passed as this parameter"""
+        return rope.base.oi.soi.get_passed_objects(
+            self.pyfunction, self.index)
+
+    def get_definition_location(self):
+        return (self.pyfunction.get_module(), self.pyfunction.get_ast().lineno)
+
+_Inferred = pynames._Inferred
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/pyobjects.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,311 @@
+from rope.base.fscommands import _decode_data
+from rope.base import ast, exceptions, utils
+
+
+class PyObject(object):
+
+    def __init__(self, type_):
+        if type_ is None:
+            type_ = self
+        self.type = type_
+
+    def get_attributes(self):
+        if self.type is self:
+            return {}
+        return self.type.get_attributes()
+
+    def get_attribute(self, name):
+        if name not in self.get_attributes():
+            raise exceptions.AttributeNotFoundError(
+                'Attribute %s not found' % name)
+        return self.get_attributes()[name]
+
+    def get_type(self):
+        return self.type
+
+    def __getitem__(self, key):
+        """The same as ``get_attribute(key)``"""
+        return self.get_attribute(key)
+
+    def __contains__(self, key):
+        """The same as ``key in self.get_attributes()``"""
+        return key in self.get_attributes()
+
+    def __eq__(self, obj):
+        """Check the equality of two `PyObject`\s
+
+        Currently it is assumed that instances (the direct instances
+        of `PyObject`, not the instances of its subclasses) are equal
+        if their types are equal.  For every other object like
+        defineds or builtins rope assumes objects are reference
+        objects and their identities should match.
+
+        """
+        if self.__class__ != obj.__class__:
+            return False
+        if type(self) == PyObject:
+            if self is not self.type:
+                return self.type == obj.type
+            else:
+                return self.type is obj.type
+        return self is obj
+
+    def __ne__(self, obj):
+        return not self.__eq__(obj)
+
+    def __hash__(self):
+        """See docs for `__eq__()` method"""
+        if type(self) == PyObject and self != self.type:
+            return hash(self.type) + 1
+        else:
+            return super(PyObject, self).__hash__()
+
+    def __iter__(self):
+        """The same as ``iter(self.get_attributes())``"""
+        return iter(self.get_attributes())
+
+    _types = None
+    _unknown = None
+
+    @staticmethod
+    def _get_base_type(name):
+        if PyObject._types is None:
+            PyObject._types = {}
+            base_type = PyObject(None)
+            PyObject._types['Type'] = base_type
+            PyObject._types['Module'] = PyObject(base_type)
+            PyObject._types['Function'] = PyObject(base_type)
+            PyObject._types['Unknown'] = PyObject(base_type)
+        return PyObject._types[name]
+
+
+def get_base_type(name):
+    """Return the base type with name `name`.
+
+    The base types are 'Type', 'Function', 'Module' and 'Unknown'.  It
+    was used to check the type of a `PyObject` but currently its use
+    is discouraged.  Use classes defined in this module instead.
+    For example instead of
+    ``pyobject.get_type() == get_base_type('Function')`` use
+    ``isinstance(pyobject, AbstractFunction)``.
+
+    You can use `AbstractClass` for classes, `AbstractFunction` for
+    functions, and `AbstractModule` for modules.  You can also use
+    `PyFunction` and `PyClass` for testing if an object is
+    defined somewhere and rope can access its source.  These classes
+    provide more methods.
+
+    """
+    return PyObject._get_base_type(name)
+
+
+def get_unknown():
+    """Return a pyobject whose type is unknown
+
+    Note that two unknown objects are equal.  So for example you can
+    write::
+
+      if pyname.get_object() == get_unknown():
+          print 'cannot determine what this pyname holds'
+
+    Rope could have used `None` for indicating unknown objects but
+    we had to check that in many places.  So actually this method
+    returns a null object.
+
+    """
+    if PyObject._unknown is None:
+        PyObject._unknown = PyObject(get_base_type('Unknown'))
+    return PyObject._unknown
+
+
+class AbstractClass(PyObject):
+
+    def __init__(self):
+        super(AbstractClass, self).__init__(get_base_type('Type'))
+
+    def get_name(self):
+        pass
+
+    def get_doc(self):
+        pass
+
+    def get_superclasses(self):
+        return []
+
+
+class AbstractFunction(PyObject):
+
+    def __init__(self):
+        super(AbstractFunction, self).__init__(get_base_type('Function'))
+
+    def get_name(self):
+        pass
+
+    def get_doc(self):
+        pass
+
+    def get_param_names(self, special_args=True):
+        return []
+
+    def get_returned_object(self, args):
+        return get_unknown()
+
+
+class AbstractModule(PyObject):
+
+    def __init__(self, doc=None):
+        super(AbstractModule, self).__init__(get_base_type('Module'))
+
+    def get_doc(self):
+        pass
+
+    def get_resource(self):
+        pass
+
+
+class PyDefinedObject(object):
+    """Python defined names that rope can access their sources"""
+
+    def __init__(self, pycore, ast_node, parent):
+        self.pycore = pycore
+        self.ast_node = ast_node
+        self.scope = None
+        self.parent = parent
+        self.structural_attributes = None
+        self.concluded_attributes = self.get_module()._get_concluded_data()
+        self.attributes = self.get_module()._get_concluded_data()
+        self.defineds = None
+
+    visitor_class = None
+
+    @utils.prevent_recursion(lambda: {})
+    def _get_structural_attributes(self):
+        if self.structural_attributes is None:
+            self.structural_attributes = self._create_structural_attributes()
+        return self.structural_attributes
+
+    @utils.prevent_recursion(lambda: {})
+    def _get_concluded_attributes(self):
+        if self.concluded_attributes.get() is None:
+            self._get_structural_attributes()
+            self.concluded_attributes.set(self._create_concluded_attributes())
+        return self.concluded_attributes.get()
+
+    def get_attributes(self):
+        if self.attributes.get() is None:
+            result = dict(self._get_concluded_attributes())
+            result.update(self._get_structural_attributes())
+            self.attributes.set(result)
+        return self.attributes.get()
+
+    def get_attribute(self, name):
+        if name in self._get_structural_attributes():
+            return self._get_structural_attributes()[name]
+        if name in self._get_concluded_attributes():
+            return self._get_concluded_attributes()[name]
+        raise exceptions.AttributeNotFoundError('Attribute %s not found' %
+                                                name)
+
+    def get_scope(self):
+        if self.scope is None:
+            self.scope = self._create_scope()
+        return self.scope
+
+    def get_module(self):
+        current_object = self
+        while current_object.parent is not None:
+            current_object = current_object.parent
+        return current_object
+
+    def get_doc(self):
+        if len(self.get_ast().body) > 0:
+            expr = self.get_ast().body[0]
+            if isinstance(expr, ast.Expr) and \
+               isinstance(expr.value, ast.Str):
+                docstring = expr.value.s
+                coding = self.get_module().coding
+                return _decode_data(docstring, coding)
+
+    def _get_defined_objects(self):
+        if self.defineds is None:
+            self._get_structural_attributes()
+        return self.defineds
+
+    def _create_structural_attributes(self):
+        if self.visitor_class is None:
+            return {}
+        new_visitor = self.visitor_class(self.pycore, self)
+        for child in ast.get_child_nodes(self.ast_node):
+            ast.walk(child, new_visitor)
+        self.defineds = new_visitor.defineds
+        return new_visitor.names
+
+    def _create_concluded_attributes(self):
+        return {}
+
+    def get_ast(self):
+        return self.ast_node
+
+    def _create_scope(self):
+        pass
+
+
+class PyFunction(PyDefinedObject, AbstractFunction):
+    """Only a placeholder"""
+
+
+class PyClass(PyDefinedObject, AbstractClass):
+    """Only a placeholder"""
+
+
+class _ConcludedData(object):
+
+    def __init__(self):
+        self.data_ = None
+
+    def set(self, data):
+        self.data_ = data
+
+    def get(self):
+        return self.data_
+
+    data = property(get, set)
+
+    def _invalidate(self):
+        self.data = None
+
+    def __str__(self):
+        return '<' + str(self.data) + '>'
+
+
+class _PyModule(PyDefinedObject, AbstractModule):
+
+    def __init__(self, pycore, ast_node, resource):
+        self.resource = resource
+        self.concluded_data = []
+        AbstractModule.__init__(self)
+        PyDefinedObject.__init__(self, pycore, ast_node, None)
+
+    def _get_concluded_data(self):
+        new_data = _ConcludedData()
+        self.concluded_data.append(new_data)
+        return new_data
+
+    def _forget_concluded_data(self):
+        for data in self.concluded_data:
+            data._invalidate()
+
+    def get_resource(self):
+        return self.resource
+
+
+class PyModule(_PyModule):
+    """Only a placeholder"""
+
+
+class PyPackage(_PyModule):
+    """Only a placeholder"""
+
+
+class IsBeingInferredError(exceptions.RopeError):
+    pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/pyobjectsdef.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,537 @@
+import rope.base.codeanalyze
+import rope.base.evaluate
+import rope.base.builtins
+import rope.base.oi.soi
+import rope.base.pyscopes
+from rope.base import (pynamesdef as pynames, exceptions, ast,
+                       astutils, pyobjects, fscommands, arguments, utils)
+from rope.base.pyobjects import *
+
+
+class PyFunction(pyobjects.PyFunction):
+
+    def __init__(self, pycore, ast_node, parent):
+        AbstractFunction.__init__(self)
+        PyDefinedObject.__init__(self, pycore, ast_node, parent)
+        self.arguments = self.ast_node.args
+        self.parameter_pyobjects = pynames._Inferred(
+            self._infer_parameters, self.get_module()._get_concluded_data())
+        self.returned = pynames._Inferred(self._infer_returned)
+        self.parameter_pynames = None
+
+    def _create_structural_attributes(self):
+        return {}
+
+    def _create_concluded_attributes(self):
+        return {}
+
+    def _create_scope(self):
+        return rope.base.pyscopes.FunctionScope(self.pycore, self,
+                                                _FunctionVisitor)
+
+    def _infer_parameters(self):
+        pyobjects = rope.base.oi.soi.infer_parameter_objects(self)
+        self._handle_special_args(pyobjects)
+        return pyobjects
+
+    def _infer_returned(self, args=None):
+        return rope.base.oi.soi.infer_returned_object(self, args)
+
+    def _handle_special_args(self, pyobjects):
+        if len(pyobjects) == len(self.arguments.args):
+            if self.arguments.vararg:
+                pyobjects.append(rope.base.builtins.get_list())
+            if self.arguments.kwarg:
+                pyobjects.append(rope.base.builtins.get_dict())
+
+    def _set_parameter_pyobjects(self, pyobjects):
+        if pyobjects is not None:
+            self._handle_special_args(pyobjects)
+        self.parameter_pyobjects.set(pyobjects)
+
+    def get_parameters(self):
+        if self.parameter_pynames is None:
+            result = {}
+            for index, name in enumerate(self.get_param_names()):
+                # TODO: handle tuple parameters
+                result[name] = pynames.ParameterName(self, index)
+            self.parameter_pynames = result
+        return self.parameter_pynames
+
+    def get_parameter(self, index):
+        if index < len(self.parameter_pyobjects.get()):
+            return self.parameter_pyobjects.get()[index]
+
+    def get_returned_object(self, args):
+        return self.returned.get(args)
+
+    def get_name(self):
+        return self.get_ast().name
+
+    def get_param_names(self, special_args=True):
+        # TODO: handle tuple parameters
+        result = [node.id for node in self.arguments.args
+                  if isinstance(node, ast.Name)]
+        if special_args:
+            if self.arguments.vararg:
+                result.append(self.arguments.vararg)
+            if self.arguments.kwarg:
+                result.append(self.arguments.kwarg)
+        return result
+
+    def get_kind(self):
+        """Get function type
+
+        It returns one of 'function', 'method', 'staticmethod' or
+        'classmethod' strs.
+
+        """
+        scope = self.parent.get_scope()
+        if isinstance(self.parent, PyClass):
+            for decorator in self.decorators:
+                pyname = rope.base.evaluate.eval_node(scope, decorator)
+                if pyname == rope.base.builtins.builtins['staticmethod']:
+                    return 'staticmethod'
+                if pyname == rope.base.builtins.builtins['classmethod']:
+                    return 'classmethod'
+            return 'method'
+        return 'function'
+
+    @property
+    def decorators(self):
+        try:
+            return getattr(self.ast_node, 'decorator_list')
+        except AttributeError:
+            return getattr(self.ast_node, 'decorators', None)
+
+
+class PyClass(pyobjects.PyClass):
+
+    def __init__(self, pycore, ast_node, parent):
+        self.visitor_class = _ClassVisitor
+        AbstractClass.__init__(self)
+        PyDefinedObject.__init__(self, pycore, ast_node, parent)
+        self.parent = parent
+        self._superclasses = self.get_module()._get_concluded_data()
+
+    def get_superclasses(self):
+        if self._superclasses.get() is None:
+            self._superclasses.set(self._get_bases())
+        return self._superclasses.get()
+
+    def get_name(self):
+        return self.get_ast().name
+
+    def _create_concluded_attributes(self):
+        result = {}
+        for base in reversed(self.get_superclasses()):
+            result.update(base.get_attributes())
+        return result
+
+    def _get_bases(self):
+        result = []
+        for base_name in self.ast_node.bases:
+            base = rope.base.evaluate.eval_node(self.parent.get_scope(),
+                                                base_name)
+            if base is not None and \
+               base.get_object().get_type() == get_base_type('Type'):
+                result.append(base.get_object())
+        return result
+
+    def _create_scope(self):
+        return rope.base.pyscopes.ClassScope(self.pycore, self)
+
+
+class PyModule(pyobjects.PyModule):
+
+    def __init__(self, pycore, source=None,
+                 resource=None, force_errors=False):
+        ignore = pycore.project.prefs.get('ignore_syntax_errors', False)
+        syntax_errors = force_errors or not ignore
+        self.has_errors = False
+        try:
+            source, node = self._init_source(pycore, source, resource)
+        except exceptions.ModuleSyntaxError:
+            self.has_errors = True
+            if syntax_errors:
+                raise
+            else:
+                source = '\n'
+                node = ast.parse('\n')
+        self.source_code = source
+        self.star_imports = []
+        self.visitor_class = _GlobalVisitor
+        self.coding = fscommands.read_str_coding(self.source_code)
+        super(PyModule, self).__init__(pycore, node, resource)
+
+    def _init_source(self, pycore, source_code, resource):
+        filename = 'string'
+        if resource:
+            filename = resource.path
+        try:
+            if source_code is None:
+                source_bytes = resource.read_bytes()
+                source_code = fscommands.file_data_to_unicode(source_bytes)
+            else:
+                if isinstance(source_code, unicode):
+                    source_bytes = fscommands.unicode_to_file_data(source_code)
+                else:
+                    source_bytes = source_code
+            ast_node = ast.parse(source_bytes, filename=filename)
+        except SyntaxError, e:
+            raise exceptions.ModuleSyntaxError(filename, e.lineno, e.msg)
+        except UnicodeDecodeError, e:
+            raise exceptions.ModuleSyntaxError(filename, 1, '%s' % (e.reason))
+        return source_code, ast_node
+
+    @utils.prevent_recursion(lambda: {})
+    def _create_concluded_attributes(self):
+        result = {}
+        for star_import in self.star_imports:
+            result.update(star_import.get_names())
+        return result
+
+    def _create_scope(self):
+        return rope.base.pyscopes.GlobalScope(self.pycore, self)
+
+    @property
+    @utils.saveit
+    def lines(self):
+        """A `SourceLinesAdapter`"""
+        return rope.base.codeanalyze.SourceLinesAdapter(self.source_code)
+
+    @property
+    @utils.saveit
+    def logical_lines(self):
+        """A `LogicalLinesFinder`"""
+        return rope.base.codeanalyze.CachingLogicalLineFinder(self.lines)
+
+
+class PyPackage(pyobjects.PyPackage):
+
+    def __init__(self, pycore, resource=None, force_errors=False):
+        self.resource = resource
+        init_dot_py = self._get_init_dot_py()
+        if init_dot_py is not None:
+            ast_node = pycore.resource_to_pyobject(
+                init_dot_py, force_errors=force_errors).get_ast()
+        else:
+            ast_node = ast.parse('\n')
+        super(PyPackage, self).__init__(pycore, ast_node, resource)
+
+    def _create_structural_attributes(self):
+        result = {}
+        modname = self.pycore.modname(self.resource)
+        extension_submodules = self.pycore._builtin_submodules(modname)
+        for name, module in extension_submodules.iteritems():
+            result[name] = rope.base.builtins.BuiltinName(module)
+        if self.resource is None:
+            return result
+        for name, resource in self._get_child_resources().items():
+            result[name] = pynames.ImportedModule(self, resource=resource)
+        return result
+
+    def _create_concluded_attributes(self):
+        result = {}
+        init_dot_py = self._get_init_dot_py()
+        if init_dot_py:
+            init_object = self.pycore.resource_to_pyobject(init_dot_py)
+            result.update(init_object.get_attributes())
+        return result
+
+    def _get_child_resources(self):
+        result = {}
+        for child in self.resource.get_children():
+            if child.is_folder():
+                result[child.name] = child
+            elif child.name.endswith('.py') and \
+                 child.name != '__init__.py':
+                name = child.name[:-3]
+                result[name] = child
+        return result
+
+    def _get_init_dot_py(self):
+        if self.resource is not None and self.resource.has_child('__init__.py'):
+            return self.resource.get_child('__init__.py')
+        else:
+            return None
+
+    def _create_scope(self):
+        return self.get_module().get_scope()
+
+    def get_module(self):
+        init_dot_py = self._get_init_dot_py()
+        if init_dot_py:
+            return self.pycore.resource_to_pyobject(init_dot_py)
+        return self
+
+
+class _AssignVisitor(object):
+
+    def __init__(self, scope_visitor):
+        self.scope_visitor = scope_visitor
+        self.assigned_ast = None
+
+    def _Assign(self, node):
+        self.assigned_ast = node.value
+        for child_node in node.targets:
+            ast.walk(child_node, self)
+
+    def _assigned(self, name, assignment=None):
+        self.scope_visitor._assigned(name, assignment)
+
+    def _Name(self, node):
+        assignment = None
+        if self.assigned_ast is not None:
+            assignment = pynames.AssignmentValue(self.assigned_ast)
+        self._assigned(node.id, assignment)
+
+    def _Tuple(self, node):
+        names = astutils.get_name_levels(node)
+        for name, levels in names:
+            assignment = None
+            if self.assigned_ast is not None:
+                assignment = pynames.AssignmentValue(self.assigned_ast, levels)
+            self._assigned(name, assignment)
+
+    def _Attribute(self, node):
+        pass
+
+    def _Subscript(self, node):
+        pass
+
+    def _Slice(self, node):
+        pass
+
+
+class _ScopeVisitor(object):
+
+    def __init__(self, pycore, owner_object):
+        self.pycore = pycore
+        self.owner_object = owner_object
+        self.names = {}
+        self.defineds = []
+
+    def get_module(self):
+        if self.owner_object is not None:
+            return self.owner_object.get_module()
+        else:
+            return None
+
+    def _ClassDef(self, node):
+        pyclass = PyClass(self.pycore, node, self.owner_object)
+        self.names[node.name] = pynames.DefinedName(pyclass)
+        self.defineds.append(pyclass)
+
+    def _FunctionDef(self, node):
+        pyfunction = PyFunction(self.pycore, node, self.owner_object)
+        for decorator in pyfunction.decorators:
+            if isinstance(decorator, ast.Name) and decorator.id == 'property':
+                if isinstance(self, _ClassVisitor):
+                    type_ = rope.base.builtins.Property(pyfunction)
+                    arg = pynames.UnboundName(PyObject(self.owner_object))
+                    def _eval(type_=type_, arg=arg):
+                        return type_.get_property_object(
+                            arguments.ObjectArguments([arg]))
+                    self.names[node.name] = pynames.EvaluatedName(
+                        _eval, module=self.get_module(), lineno=node.lineno)
+                    break
+        else:
+            self.names[node.name] = pynames.DefinedName(pyfunction)
+        self.defineds.append(pyfunction)
+
+    def _Assign(self, node):
+        ast.walk(node, _AssignVisitor(self))
+
+    def _AugAssign(self, node):
+        pass
+
+    def _For(self, node):
+        names = self._update_evaluated(node.target, node.iter,
+                                       '.__iter__().next()')
+        for child in node.body + node.orelse:
+            ast.walk(child, self)
+
+    def _assigned(self, name, assignment):
+        pyname = self.names.get(name, None)
+        if pyname is None:
+            pyname = pynames.AssignedName(module=self.get_module())
+        if isinstance(pyname, pynames.AssignedName):
+            if assignment is not None:
+                pyname.assignments.append(assignment)
+            self.names[name] = pyname
+
+    def _update_evaluated(self, targets, assigned,
+                          evaluation= '', eval_type=False):
+        result = {}
+        names = astutils.get_name_levels(targets)
+        for name, levels in names:
+            assignment = pynames.AssignmentValue(assigned, levels,
+                                                 evaluation, eval_type)
+            self._assigned(name, assignment)
+        return result
+
+    def _With(self, node):
+        if node.optional_vars:
+            self._update_evaluated(node.optional_vars,
+                                   node.context_expr, '.__enter__()')
+        for child in node.body:
+            ast.walk(child, self)
+
+    def _excepthandler(self, node):
+        if node.name is not None and isinstance(node.name, ast.Name):
+            type_node = node.type
+            if isinstance(node.type, ast.Tuple) and type_node.elts:
+                type_node = type_node.elts[0]
+            self._update_evaluated(node.name, type_node, eval_type=True)
+        for child in node.body:
+            ast.walk(child, self)
+
+    def _ExceptHandler(self, node):
+        self._excepthandler(node)
+
+    def _Import(self, node):
+        for import_pair in node.names:
+            module_name = import_pair.name
+            alias = import_pair.asname
+            first_package = module_name.split('.')[0]
+            if alias is not None:
+                imported = pynames.ImportedModule(self.get_module(),
+                                                  module_name)
+                if not self._is_ignored_import(imported):
+                    self.names[alias] = imported
+            else:
+                imported = pynames.ImportedModule(self.get_module(),
+                                                  first_package)
+                if not self._is_ignored_import(imported):
+                    self.names[first_package] = imported
+
+    def _ImportFrom(self, node):
+        level = 0
+        if node.level:
+            level = node.level
+        imported_module = pynames.ImportedModule(self.get_module(),
+                                                 node.module, level)
+        if self._is_ignored_import(imported_module):
+            return
+        if len(node.names) == 1 and node.names[0].name == '*':
+            if isinstance(self.owner_object, PyModule):
+                self.owner_object.star_imports.append(
+                    StarImport(imported_module))
+        else:
+            for imported_name in node.names:
+                imported = imported_name.name
+                alias = imported_name.asname
+                if alias is not None:
+                    imported = alias
+                self.names[imported] = pynames.ImportedName(imported_module,
+                                                            imported_name.name)
+
+    def _is_ignored_import(self, imported_module):
+        if not self.pycore.project.prefs.get('ignore_bad_imports', False):
+            return False
+        return not isinstance(imported_module.get_object(), AbstractModule)
+
+    def _Global(self, node):
+        module = self.get_module()
+        for name in node.names:
+            if module is not None:
+                try:
+                    pyname = module[name]
+                except exceptions.AttributeNotFoundError:
+                    pyname = pynames.AssignedName(node.lineno)
+            self.names[name] = pyname
+
+
+class _GlobalVisitor(_ScopeVisitor):
+
+    def __init__(self, pycore, owner_object):
+        super(_GlobalVisitor, self).__init__(pycore, owner_object)
+
+
+class _ClassVisitor(_ScopeVisitor):
+
+    def __init__(self, pycore, owner_object):
+        super(_ClassVisitor, self).__init__(pycore, owner_object)
+
+    def _FunctionDef(self, node):
+        _ScopeVisitor._FunctionDef(self, node)
+        if len(node.args.args) > 0:
+            first = node.args.args[0]
+            if isinstance(first, ast.Name):
+                new_visitor = _ClassInitVisitor(self, first.id)
+                for child in ast.get_child_nodes(node):
+                    ast.walk(child, new_visitor)
+
+
+class _FunctionVisitor(_ScopeVisitor):
+
+    def __init__(self, pycore, owner_object):
+        super(_FunctionVisitor, self).__init__(pycore, owner_object)
+        self.returned_asts = []
+        self.generator = False
+
+    def _Return(self, node):
+        if node.value is not None:
+            self.returned_asts.append(node.value)
+
+    def _Yield(self, node):
+        if node.value is not None:
+            self.returned_asts.append(node.value)
+        self.generator = True
+
+
+class _ClassInitVisitor(_AssignVisitor):
+
+    def __init__(self, scope_visitor, self_name):
+        super(_ClassInitVisitor, self).__init__(scope_visitor)
+        self.self_name = self_name
+
+    def _Attribute(self, node):
+        if not isinstance(node.ctx, ast.Store):
+            return
+        if isinstance(node.value, ast.Name) and \
+           node.value.id == self.self_name:
+            if node.attr not in self.scope_visitor.names:
+                self.scope_visitor.names[node.attr] = pynames.AssignedName(
+                    lineno=node.lineno, module=self.scope_visitor.get_module())
+            if self.assigned_ast is not None:
+                pyname = self.scope_visitor.names[node.attr]
+                if isinstance(pyname, pynames.AssignedName):
+                    pyname.assignments.append(
+                        pynames.AssignmentValue(self.assigned_ast))
+
+    def _Tuple(self, node):
+        if not isinstance(node.ctx, ast.Store):
+            return
+        for child in ast.get_child_nodes(node):
+            ast.walk(child, self)
+
+    def _Name(self, node):
+        pass
+
+    def _FunctionDef(self, node):
+        pass
+
+    def _ClassDef(self, node):
+        pass
+
+    def _For(self, node):
+        pass
+
+    def _With(self, node):
+        pass
+
+
+class StarImport(object):
+
+    def __init__(self, imported_module):
+        self.imported_module = imported_module
+
+    def get_names(self):
+        result = {}
+        imported = self.imported_module.get_object()
+        for name in imported:
+            if not name.startswith('_'):
+                result[name] = pynames.ImportedName(self.imported_module, name)
+        return result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/pyscopes.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,313 @@
+import rope.base.builtins
+import rope.base.codeanalyze
+import rope.base.pynames
+from rope.base import ast, exceptions, utils
+
+
+class Scope(object):
+
+    def __init__(self, pycore, pyobject, parent_scope):
+        self.pycore = pycore
+        self.pyobject = pyobject
+        self.parent = parent_scope
+
+    def get_names(self):
+        """Return the names defined or imported in this scope"""
+        return self.pyobject.get_attributes()
+
+    def get_defined_names(self):
+        """Return the names defined in this scope"""
+        return self.pyobject._get_structural_attributes()
+
+    def get_name(self, name):
+        """Return name `PyName` defined in this scope"""
+        if name not in self.get_names():
+            raise exceptions.NameNotFoundError('name %s not found' % name)
+        return self.get_names()[name]
+
+    def __getitem__(self, key):
+        """The same as ``get_name(key)``"""
+        return self.get_name(key)
+
+    def __contains__(self, key):
+        """The same as ``key in self.get_names()``"""
+        return key in self.get_names()
+
+    @utils.saveit
+    def get_scopes(self):
+        """Return the subscopes of this scope
+
+        The returned scopes should be sorted by the order they appear.
+        """
+        return self._create_scopes()
+
+    def lookup(self, name):
+        if name in self.get_names():
+            return self.get_names()[name]
+        if self.parent is not None:
+            return self.parent._propagated_lookup(name)
+        return None
+
+    def get_propagated_names(self):
+        """Return the visible names of this scope
+
+        Return the names defined in this scope that are visible from
+        scopes containing this scope.  This method returns the same
+        dictionary returned by `get_names()` except for `ClassScope`
+        which returns an empty dict.
+        """
+        return self.get_names()
+
+    def _propagated_lookup(self, name):
+        if name in self.get_propagated_names():
+            return self.get_propagated_names()[name]
+        if self.parent is not None:
+            return self.parent._propagated_lookup(name)
+        return None
+
+    def _create_scopes(self):
+        return [pydefined.get_scope()
+                for pydefined in self.pyobject._get_defined_objects()]
+
+    def _get_global_scope(self):
+        current = self
+        while current.parent is not None:
+            current = current.parent
+        return current
+
+    def get_start(self):
+        return self.pyobject.get_ast().lineno
+
+    def get_body_start(self):
+        body = self.pyobject.get_ast().body
+        if body:
+            return body[0].lineno
+        return self.get_start()
+
+    def get_end(self):
+        pymodule = self._get_global_scope().pyobject
+        return pymodule.logical_lines.logical_line_in(self.logical_end)[1]
+
+    @utils.saveit
+    def get_logical_end(self):
+        global_scope = self._get_global_scope()
+        return global_scope._scope_finder.find_scope_end(self)
+
+    start = property(get_start)
+    end = property(get_end)
+    logical_end = property(get_logical_end)
+
+    def get_kind(self):
+        pass
+
+
+class GlobalScope(Scope):
+
+    def __init__(self, pycore, module):
+        super(GlobalScope, self).__init__(pycore, module, None)
+        self.names = module._get_concluded_data()
+
+    def get_start(self):
+        return 1
+
+    def get_kind(self):
+        return 'Module'
+
+    def get_name(self, name):
+        try:
+            return self.pyobject[name]
+        except exceptions.AttributeNotFoundError:
+            if name in self.builtin_names:
+                return self.builtin_names[name]
+            raise exceptions.NameNotFoundError('name %s not found' % name)
+
+    def get_names(self):
+        if self.names.get() is None:
+            result = dict(self.builtin_names)
+            result.update(super(GlobalScope, self).get_names())
+            self.names.set(result)
+        return self.names.get()
+
+    def get_inner_scope_for_line(self, lineno, indents=None):
+        return self._scope_finder.get_holding_scope(self, lineno, indents)
+
+    def get_inner_scope_for_offset(self, offset):
+        return self._scope_finder.get_holding_scope_for_offset(self, offset)
+
+    @property
+    @utils.saveit
+    def _scope_finder(self):
+        return _HoldingScopeFinder(self.pyobject)
+
+    @property
+    def builtin_names(self):
+        return rope.base.builtins.builtins.get_attributes()
+
+
+class FunctionScope(Scope):
+
+    def __init__(self, pycore, pyobject, visitor):
+        super(FunctionScope, self).__init__(pycore, pyobject,
+                                            pyobject.parent.get_scope())
+        self.names = None
+        self.returned_asts = None
+        self.is_generator = None
+        self.defineds = None
+        self.visitor = visitor
+
+    def _get_names(self):
+        if self.names is None:
+            self._visit_function()
+        return self.names
+
+    def _visit_function(self):
+        if self.names is None:
+            new_visitor = self.visitor(self.pycore, self.pyobject)
+            for n in ast.get_child_nodes(self.pyobject.get_ast()):
+                ast.walk(n, new_visitor)
+            self.names = new_visitor.names
+            self.names.update(self.pyobject.get_parameters())
+            self.returned_asts = new_visitor.returned_asts
+            self.is_generator = new_visitor.generator
+            self.defineds = new_visitor.defineds
+
+    def _get_returned_asts(self):
+        if self.names is None:
+            self._visit_function()
+        return self.returned_asts
+
+    def _is_generator(self):
+        if self.is_generator is None:
+            self._get_returned_asts()
+        return self.is_generator
+
+    def get_names(self):
+        return self._get_names()
+
+    def _create_scopes(self):
+        if self.defineds is None:
+            self._visit_function()
+        return [pydefined.get_scope() for pydefined in self.defineds]
+
+    def get_kind(self):
+        return 'Function'
+
+    def invalidate_data(self):
+        for pyname in self.get_names().values():
+            if isinstance(pyname, (rope.base.pynames.AssignedName,
+                                   rope.base.pynames.EvaluatedName)):
+                pyname.invalidate()
+
+
+class ClassScope(Scope):
+
+    def __init__(self, pycore, pyobject):
+        super(ClassScope, self).__init__(pycore, pyobject,
+                                         pyobject.parent.get_scope())
+
+    def get_kind(self):
+        return 'Class'
+
+    def get_propagated_names(self):
+        return {}
+
+
+class _HoldingScopeFinder(object):
+
+    def __init__(self, pymodule):
+        self.pymodule = pymodule
+
+    def get_indents(self, lineno):
+        return rope.base.codeanalyze.count_line_indents(
+            self.lines.get_line(lineno))
+
+    def _get_scope_indents(self, scope):
+        return self.get_indents(scope.get_start())
+
+    def get_holding_scope(self, module_scope, lineno, line_indents=None):
+        if line_indents is None:
+            line_indents = self.get_indents(lineno)
+        current_scope = module_scope
+        new_scope = current_scope
+        while new_scope is not None and \
+              (new_scope.get_kind() == 'Module' or
+               self._get_scope_indents(new_scope) <= line_indents):
+            current_scope = new_scope
+            if current_scope.get_start() == lineno and \
+               current_scope.get_kind() != 'Module':
+                return current_scope
+            new_scope = None
+            for scope in current_scope.get_scopes():
+                if scope.get_start() <= lineno:
+                    if lineno <= scope.get_end():
+                        new_scope = scope
+                        break
+                else:
+                    break
+        return current_scope
+
+    def _is_empty_line(self, lineno):
+        line = self.lines.get_line(lineno)
+        return line.strip() == '' or line.lstrip().startswith('#')
+
+    def _get_body_indents(self, scope):
+        return self.get_indents(scope.get_body_start())
+
+    def get_holding_scope_for_offset(self, scope, offset):
+        return self.get_holding_scope(
+            scope, self.lines.get_line_number(offset))
+
+    def find_scope_end(self, scope):
+        if not scope.parent:
+            return self.lines.length()
+        end = scope.pyobject.get_ast().body[-1].lineno
+        scope_start = self.pymodule.logical_lines.logical_line_in(scope.start)
+        if scope_start[1] >= end:
+            # handling one-liners
+            body_indents = self._get_scope_indents(scope) + 4
+        else:
+            body_indents = self._get_body_indents(scope)
+        for l in self.logical_lines.generate_starts(
+            min(end + 1, self.lines.length()), self.lines.length() + 1):
+            if not self._is_empty_line(l):
+                if self.get_indents(l) < body_indents:
+                    return end
+                else:
+                    end = l
+        return end
+
+    @property
+    def lines(self):
+        return self.pymodule.lines
+
+    @property
+    def code(self):
+        return self.pymodule.source_code
+
+    @property
+    def logical_lines(self):
+        return self.pymodule.logical_lines
+
+class TemporaryScope(Scope):
+    """Currently used for list comprehensions and generator expressions
+
+    These scopes do not appear in the `get_scopes()` method of their
+    parent scopes.
+    """
+
+    def __init__(self, pycore, parent_scope, names):
+        super(TemporaryScope, self).__init__(
+            pycore, parent_scope.pyobject, parent_scope)
+        self.names = names
+
+    def get_names(self):
+        return self.names
+
+    def get_defined_names(self):
+        return self.names
+
+    def _create_scopes(self):
+        return []
+
+    def get_kind(self):
+        return 'Temporary'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/resourceobserver.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,271 @@
+import os
+
+
+class ResourceObserver(object):
+    """Provides the interface for observing resources
+
+    `ResourceObserver`\s can be registered using `Project.
+    add_observer()`.  But most of the time `FilteredResourceObserver`
+    should be used.  `ResourceObserver`\s report all changes passed
+    to them and they don't report changes to all resources.  For
+    example if a folder is removed, it only calls `removed()` for that
+    folder and not its contents.  You can use
+    `FilteredResourceObserver` if you are interested in changes only
+    to a list of resources.  And you want changes to be reported on
+    individual resources.
+
+    """
+
+    def __init__(self, changed=None, moved=None, created=None,
+                 removed=None, validate=None):
+        self.changed = changed
+        self.moved = moved
+        self.created = created
+        self.removed = removed
+        self._validate = validate
+
+    def resource_changed(self, resource):
+        """It is called when the resource changes"""
+        if self.changed is not None:
+            self.changed(resource)
+
+    def resource_moved(self, resource, new_resource):
+        """It is called when a resource is moved"""
+        if self.moved is not None:
+            self.moved(resource, new_resource)
+
+    def resource_created(self, resource):
+        """Is called when a new resource is created"""
+        if self.created is not None:
+            self.created(resource)
+
+    def resource_removed(self, resource):
+        """Is called when a new resource is removed"""
+        if self.removed is not None:
+            self.removed(resource)
+
+    def validate(self, resource):
+        """Validate the existence of this resource and its children.
+
+        This function is called when rope need to update its resource
+        cache about the files that might have been changed or removed
+        by other processes.
+
+        """
+        if self._validate is not None:
+            self._validate(resource)
+
+
+class FilteredResourceObserver(object):
+    """A useful decorator for `ResourceObserver`
+
+    Most resource observers have a list of resources and are
+    interested only in changes to those files.  This class satisfies
+    this need.  It dispatches resource changed and removed messages.
+    It performs these tasks:
+
+    * Changes to files and folders are analyzed to check whether any
+      of the interesting resources are changed or not.  If they are,
+      it reports these changes to `resource_observer` passed to the
+      constructor.
+    * When a resource is removed it checks whether any of the
+      interesting resources are contained in that folder and reports
+      them to `resource_observer`.
+    * When validating a folder it validates all of the interesting
+      files in that folder.
+
+    Since most resource observers are interested in a list of
+    resources that change over time, `add_resource` and
+    `remove_resource` might be useful.
+
+    """
+
+    def __init__(self, resource_observer, initial_resources=None,
+                 timekeeper=None):
+        self.observer = resource_observer
+        self.resources = {}
+        if timekeeper is not None:
+            self.timekeeper = timekeeper
+        else:
+            self.timekeeper = ChangeIndicator()
+        if initial_resources is not None:
+            for resource in initial_resources:
+                self.add_resource(resource)
+
+    def add_resource(self, resource):
+        """Add a resource to the list of interesting resources"""
+        if resource.exists():
+            self.resources[resource] = self.timekeeper.get_indicator(resource)
+        else:
+            self.resources[resource] = None
+
+    def remove_resource(self, resource):
+        """Add a resource to the list of interesting resources"""
+        if resource in self.resources:
+            del self.resources[resource]
+
+    def clear_resources(self):
+        """Removes all registered resources"""
+        self.resources.clear()
+
+    def resource_changed(self, resource):
+        changes = _Changes()
+        self._update_changes_caused_by_changed(changes, resource)
+        self._perform_changes(changes)
+
+    def _update_changes_caused_by_changed(self, changes, changed):
+        if changed in self.resources:
+            changes.add_changed(changed)
+        if self._is_parent_changed(changed):
+            changes.add_changed(changed.parent)
+
+    def _update_changes_caused_by_moved(self, changes, resource,
+                                        new_resource=None):
+        if resource in self.resources:
+            changes.add_removed(resource, new_resource)
+        if new_resource in self.resources:
+            changes.add_created(new_resource)
+        if resource.is_folder():
+            for file in list(self.resources):
+                if resource.contains(file):
+                    new_file = self._calculate_new_resource(
+                        resource, new_resource, file)
+                    changes.add_removed(file, new_file)
+        if self._is_parent_changed(resource):
+            changes.add_changed(resource.parent)
+        if new_resource is not None:
+            if self._is_parent_changed(new_resource):
+                changes.add_changed(new_resource.parent)
+
+    def _is_parent_changed(self, child):
+        return child.parent in self.resources
+
+    def resource_moved(self, resource, new_resource):
+        changes = _Changes()
+        self._update_changes_caused_by_moved(changes, resource, new_resource)
+        self._perform_changes(changes)
+
+    def resource_created(self, resource):
+        changes = _Changes()
+        self._update_changes_caused_by_created(changes, resource)
+        self._perform_changes(changes)
+
+    def _update_changes_caused_by_created(self, changes, resource):
+        if resource in self.resources:
+            changes.add_created(resource)
+        if self._is_parent_changed(resource):
+            changes.add_changed(resource.parent)
+
+    def resource_removed(self, resource):
+        changes = _Changes()
+        self._update_changes_caused_by_moved(changes, resource)
+        self._perform_changes(changes)
+
+    def _perform_changes(self, changes):
+        for resource in changes.changes:
+            self.observer.resource_changed(resource)
+            self.resources[resource] = self.timekeeper.get_indicator(resource)
+        for resource, new_resource in changes.moves.items():
+            self.resources[resource] = None
+            if new_resource is not None:
+                self.observer.resource_moved(resource, new_resource)
+            else:
+                self.observer.resource_removed(resource)
+        for resource in changes.creations:
+            self.observer.resource_created(resource)
+            self.resources[resource] = self.timekeeper.get_indicator(resource)
+
+    def validate(self, resource):
+        changes = _Changes()
+        for file in self._search_resource_moves(resource):
+            if file in self.resources:
+                self._update_changes_caused_by_moved(changes, file)
+        for file in self._search_resource_changes(resource):
+            if file in self.resources:
+                self._update_changes_caused_by_changed(changes, file)
+        for file in self._search_resource_creations(resource):
+            if file in self.resources:
+                changes.add_created(file)
+        self._perform_changes(changes)
+
+    def _search_resource_creations(self, resource):
+        creations = set()
+        if resource in self.resources and resource.exists() and \
+           self.resources[resource] is None:
+            creations.add(resource)
+        if resource.is_folder():
+            for file in self.resources:
+                if file.exists() and resource.contains(file) and \
+                   self.resources[file] is None:
+                    creations.add(file)
+        return creations
+
+    def _search_resource_moves(self, resource):
+        all_moved = set()
+        if resource in self.resources and not resource.exists():
+            all_moved.add(resource)
+        if resource.is_folder():
+            for file in self.resources:
+                if resource.contains(file):
+                    if not file.exists():
+                        all_moved.add(file)
+        moved = set(all_moved)
+        for folder in [file for file in all_moved if file.is_folder()]:
+            if folder in moved:
+                for file in list(moved):
+                    if folder.contains(file):
+                        moved.remove(file)
+        return moved
+
+    def _search_resource_changes(self, resource):
+        changed = set()
+        if resource in self.resources and self._is_changed(resource):
+            changed.add(resource)
+        if resource.is_folder():
+            for file in self.resources:
+                if file.exists() and resource.contains(file):
+                    if self._is_changed(file):
+                        changed.add(file)
+        return changed
+
+    def _is_changed(self, resource):
+        if self.resources[resource] is None:
+            return False
+        return self.resources[resource] != self.timekeeper.get_indicator(resource)
+
+    def _calculate_new_resource(self, main, new_main, resource):
+        if new_main is None:
+            return None
+        diff = resource.path[len(main.path):]
+        return resource.project.get_resource(new_main.path + diff)
+
+
+class ChangeIndicator(object):
+
+    def get_indicator(self, resource):
+        """Return the modification time and size of a `Resource`."""
+        path = resource.real_path
+        # on dos, mtime does not change for a folder when files are added
+        if os.name != 'posix' and os.path.isdir(path):
+            return (os.path.getmtime(path),
+                    len(os.listdir(path)),
+                    os.path.getsize(path))
+        return (os.path.getmtime(path),
+                os.path.getsize(path))
+
+
+class _Changes(object):
+
+    def __init__(self):
+        self.changes = set()
+        self.creations = set()
+        self.moves = {}
+
+    def add_changed(self, resource):
+        self.changes.add(resource)
+
+    def add_removed(self, resource, new_resource=None):
+        self.moves[resource] = new_resource
+
+    def add_created(self, resource):
+        self.creations.add(resource)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/resources.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,211 @@
+import os
+import re
+
+import rope.base.change
+import rope.base.fscommands
+from rope.base import exceptions
+
+
+class Resource(object):
+    """Represents files and folders in a project"""
+
+    def __init__(self, project, path):
+        self.project = project
+        self._path = path
+
+    def move(self, new_location):
+        """Move resource to `new_location`"""
+        self._perform_change(rope.base.change.MoveResource(self, new_location),
+                             'Moving <%s> to <%s>' % (self.path, new_location))
+
+    def remove(self):
+        """Remove resource from the project"""
+        self._perform_change(rope.base.change.RemoveResource(self),
+                             'Removing <%s>' % self.path)
+
+    def is_folder(self):
+        """Return true if the resource is a folder"""
+
+    def create(self):
+        """Create this resource"""
+
+    def exists(self):
+        return os.path.exists(self.real_path)
+
+    @property
+    def parent(self):
+        parent = '/'.join(self.path.split('/')[0:-1])
+        return self.project.get_folder(parent)
+
+    @property
+    def path(self):
+        """Return the path of this resource relative to the project root
+
+        The path is the list of parent directories separated by '/' followed
+        by the resource name.
+        """
+        return self._path
+
+    @property
+    def name(self):
+        """Return the name of this resource"""
+        return self.path.split('/')[-1]
+
+    @property
+    def real_path(self):
+        """Return the file system path of this resource"""
+        return self.project._get_resource_path(self.path)
+
+    def __eq__(self, obj):
+        return self.__class__ == obj.__class__ and self.path == obj.path
+
+    def __ne__(self, obj):
+        return not self.__eq__(obj)
+
+    def __hash__(self):
+        return hash(self.path)
+
+    def _perform_change(self, change_, description):
+        changes = rope.base.change.ChangeSet(description)
+        changes.add_change(change_)
+        self.project.do(changes)
+
+
+class File(Resource):
+    """Represents a file"""
+
+    def __init__(self, project, name):
+        super(File, self).__init__(project, name)
+
+    def read(self):
+        data = self.read_bytes()
+        try:
+            return rope.base.fscommands.file_data_to_unicode(data)
+        except UnicodeDecodeError, e:
+            raise exceptions.ModuleDecodeError(self.path, e.reason)
+
+    def read_bytes(self):
+        return open(self.real_path, 'rb').read()
+
+    def write(self, contents):
+        try:
+            if contents == self.read():
+                return
+        except IOError:
+            pass
+        self._perform_change(rope.base.change.ChangeContents(self, contents),
+                             'Writing file <%s>' % self.path)
+
+    def is_folder(self):
+        return False
+
+    def create(self):
+        self.parent.create_file(self.name)
+
+
+class Folder(Resource):
+    """Represents a folder"""
+
+    def __init__(self, project, name):
+        super(Folder, self).__init__(project, name)
+
+    def is_folder(self):
+        return True
+
+    def get_children(self):
+        """Return the children of this folder"""
+        result = []
+        for name in os.listdir(self.real_path):
+            try:
+                child = self.get_child(name)
+            except exceptions.ResourceNotFoundError:
+                continue
+            if not self.project.is_ignored(child):
+                result.append(self.get_child(name))
+        return result
+
+    def create_file(self, file_name):
+        self._perform_change(
+            rope.base.change.CreateFile(self, file_name),
+            'Creating file <%s>' % self._get_child_path(file_name))
+        return self.get_child(file_name)
+
+    def create_folder(self, folder_name):
+        self._perform_change(
+            rope.base.change.CreateFolder(self, folder_name),
+            'Creating folder <%s>' % self._get_child_path(folder_name))
+        return self.get_child(folder_name)
+
+    def _get_child_path(self, name):
+        if self.path:
+            return self.path + '/' + name
+        else:
+            return name
+
+    def get_child(self, name):
+        return self.project.get_resource(self._get_child_path(name))
+
+    def has_child(self, name):
+        try:
+            self.get_child(name)
+            return True
+        except exceptions.ResourceNotFoundError:
+            return False
+
+    def get_files(self):
+        return [resource for resource in self.get_children()
+                if not resource.is_folder()]
+
+    def get_folders(self):
+        return [resource for resource in self.get_children()
+                if resource.is_folder()]
+
+    def contains(self, resource):
+        if self == resource:
+            return False
+        return self.path == '' or resource.path.startswith(self.path + '/')
+
+    def create(self):
+        self.parent.create_folder(self.name)
+
+
+class _ResourceMatcher(object):
+
+    def __init__(self):
+        self.patterns = []
+        self._compiled_patterns = []
+
+    def set_patterns(self, patterns):
+        """Specify which resources to match
+
+        `patterns` is a `list` of `str`\s that can contain ``*`` and
+        ``?`` signs for matching resource names.
+
+        """
+        self._compiled_patterns = None
+        self.patterns = patterns
+
+    def _add_pattern(self, pattern):
+        re_pattern = pattern.replace('.', '\\.').\
+                     replace('*', '[^/]*').replace('?', '[^/]').\
+                     replace('//', '/(.*/)?')
+        re_pattern = '^(.*/)?' + re_pattern + '(/.*)?$'
+        self.compiled_patterns.append(re.compile(re_pattern))
+
+    def does_match(self, resource):
+        for pattern in self.compiled_patterns:
+            if pattern.match(resource.path):
+                return True
+        path = os.path.join(resource.project.address,
+                            *resource.path.split('/'))
+        if os.path.islink(path):
+            return True
+        return False
+
+    @property
+    def compiled_patterns(self):
+        if self._compiled_patterns is None:
+            self._compiled_patterns = []
+            for pattern in self.patterns:
+                self._add_pattern(pattern)
+        return self._compiled_patterns
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/simplify.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,55 @@
+"""A module to ease code analysis
+
+This module is here to help source code analysis.
+"""
+import re
+
+from rope.base import codeanalyze, utils
+
+
+@utils.cached(7)
+def real_code(source):
+    """Simplify `source` for analysis
+
+    It replaces:
+
+    * comments with spaces
+    * strs with a new str filled with spaces
+    * implicit and explicit continuations with spaces
+    * tabs and semicolons with spaces
+
+    The resulting code is a lot easier to analyze if we are interested
+    only in offsets.
+    """
+    collector = codeanalyze.ChangeCollector(source)
+    for start, end in ignored_regions(source):
+        if source[start] == '#':
+            replacement = ' ' * (end - start)
+        else:
+            replacement = '"%s"' % (' ' * (end - start - 2))
+        collector.add_change(start, end, replacement)
+    source = collector.get_changed() or source
+    collector = codeanalyze.ChangeCollector(source)
+    parens = 0
+    for match in _parens.finditer(source):
+        i = match.start()
+        c = match.group()
+        if c in '({[':
+            parens += 1
+        if c in ')}]':
+            parens -= 1
+        if c == '\n' and parens > 0:
+            collector.add_change(i, i + 1, ' ')
+    source = collector.get_changed() or source
+    return source.replace('\\\n', '  ').replace('\t', ' ').replace(';', '\n')
+
+
+@utils.cached(7)
+def ignored_regions(source):
+    """Return ignored regions like strings and comments in `source` """
+    return [(match.start(), match.end()) for match in _str.finditer(source)]
+
+
+_str = re.compile('%s|%s' % (codeanalyze.get_comment_pattern(),
+                             codeanalyze.get_string_pattern()))
+_parens = re.compile(r'[\({\[\]}\)\n]')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/stdmods.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,40 @@
+import os
+import sys
+
+from rope.base import utils
+
+
+def _stdlib_path():
+    import inspect
+    return os.path.dirname(inspect.getsourcefile(inspect))
+
+@utils.cached(1)
+def standard_modules():
+    return python_modules() | dynload_modules()
+
+@utils.cached(1)
+def python_modules():
+    result = set()
+    lib_path = _stdlib_path()
+    if os.path.exists(lib_path):
+        for name in os.listdir(lib_path):
+            path = os.path.join(lib_path, name)
+            if os.path.isdir(path):
+                if '-' not in name:
+                    result.add(name)
+            else:
+                if name.endswith('.py'):
+                    result.add(name[:-3])
+    return result
+
+@utils.cached(1)
+def dynload_modules():
+    result = set(sys.builtin_module_names)
+    dynload_path = os.path.join(_stdlib_path(), 'lib-dynload')
+    if os.path.exists(dynload_path):
+        for name in os.listdir(dynload_path):
+            path = os.path.join(dynload_path, name)
+            if os.path.isfile(path):
+                if name.endswith('.so') or name.endswith('.dll'):
+                    result.add(os.path.splitext(name)[0])
+    return result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/taskhandle.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,133 @@
+import warnings
+
+from rope.base import exceptions
+
+
+class TaskHandle(object):
+
+    def __init__(self, name='Task', interrupts=True):
+        """Construct a TaskHandle
+
+        If `interrupts` is `False` the task won't be interrupted by
+        calling `TaskHandle.stop()`.
+
+        """
+        self.name = name
+        self.interrupts = interrupts
+        self.stopped = False
+        self.job_sets = []
+        self.observers = []
+
+    def stop(self):
+        """Interrupts the refactoring"""
+        if self.interrupts:
+            self.stopped = True
+            self._inform_observers()
+
+    def current_jobset(self):
+        """Return the current `JobSet`"""
+        if self.job_sets:
+            return self.job_sets[-1]
+
+    def add_observer(self, observer):
+        """Register an observer for this task handle
+
+        The observer is notified whenever the task is stopped or
+        a job gets finished.
+
+        """
+        self.observers.append(observer)
+
+    def is_stopped(self):
+        return self.stopped
+
+    def get_jobsets(self):
+        return self.job_sets
+
+    def create_jobset(self, name='JobSet', count=None):
+        result = JobSet(self, name=name, count=count)
+        self.job_sets.append(result)
+        self._inform_observers()
+        return result
+
+    def _inform_observers(self):
+        for observer in list(self.observers):
+            observer()
+
+
+class JobSet(object):
+
+    def __init__(self, handle, name, count):
+        self.handle = handle
+        self.name = name
+        self.count = count
+        self.done = 0
+        self.job_name = None
+
+    def started_job(self, name):
+        self.check_status()
+        self.job_name = name
+        self.handle._inform_observers()
+
+    def finished_job(self):
+        self.check_status()
+        self.done += 1
+        self.handle._inform_observers()
+        self.job_name = None
+
+    def check_status(self):
+        if self.handle.is_stopped():
+            raise exceptions.InterruptedTaskError()
+
+    def get_active_job_name(self):
+        return self.job_name
+
+    def get_percent_done(self):
+        if self.count is not None and self.count > 0:
+            percent = self.done * 100 // self.count
+            return min(percent, 100)
+
+    def get_name(self):
+        return self.name
+
+
+class NullTaskHandle(object):
+
+    def __init__(self):
+        pass
+
+    def is_stopped(self):
+        return False
+
+    def stop(self):
+        pass
+
+    def create_jobset(self, *args, **kwds):
+        return NullJobSet()
+
+    def get_jobsets(self):
+        return []
+
+    def add_observer(self, observer):
+        pass
+
+
+class NullJobSet(object):
+
+    def started_job(self, name):
+        pass
+
+    def finished_job(self):
+        pass
+
+    def check_status(self):
+        pass
+
+    def get_active_job_name(self):
+        pass
+
+    def get_percent_done(self):
+        pass
+
+    def get_name(self):
+        pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/utils.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,78 @@
+import warnings
+
+
+def saveit(func):
+    """A decorator that caches the return value of a function"""
+
+    name = '_' + func.__name__
+    def _wrapper(self, *args, **kwds):
+        if not hasattr(self, name):
+            setattr(self, name, func(self, *args, **kwds))
+        return getattr(self, name)
+    return _wrapper
+
+cacheit = saveit
+
+def prevent_recursion(default):
+    """A decorator that returns the return value of `default` in recursions"""
+    def decorator(func):
+        name = '_calling_%s_' % func.__name__
+        def newfunc(self, *args, **kwds):
+            if getattr(self, name, False):
+                return default()
+            setattr(self, name, True)
+            try:
+                return func(self, *args, **kwds)
+            finally:
+                setattr(self, name, False)
+        return newfunc
+    return decorator
+
+
+def ignore_exception(exception_class):
+    """A decorator that ignores `exception_class` exceptions"""
+    def _decorator(func):
+        def newfunc(*args, **kwds):
+            try:
+                return func(*args, **kwds)
+            except exception_class:
+                pass
+        return newfunc
+    return _decorator
+
+
+def deprecated(message=None):
+    """A decorator for deprecated functions"""
+    def _decorator(func, message=message):
+        if message is None:
+            message = '%s is deprecated' % func.__name__
+        def newfunc(*args, **kwds):
+            warnings.warn(message, DeprecationWarning, stacklevel=2)
+            return func(*args, **kwds)
+        return newfunc
+    return _decorator
+
+
+def cached(count):
+    """A caching decorator based on parameter objects"""
+    def decorator(func):
+        return _Cached(func, count)
+    return decorator
+
+class _Cached(object):
+
+    def __init__(self, func, count):
+        self.func = func
+        self.cache = []
+        self.count = count
+
+    def __call__(self, *args, **kwds):
+        key = (args, kwds)
+        for cached_key, cached_result in self.cache:
+            if cached_key == key:
+                return cached_result
+        result = self.func(*args, **kwds)
+        self.cache.append((key, result))
+        if len(self.cache) > self.count:
+            del self.cache[0]
+        return result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/base/worder.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,521 @@
+import bisect
+import keyword
+
+import rope.base.simplify
+
+
+def get_name_at(resource, offset):
+    source_code = resource.read()
+    word_finder = Worder(source_code)
+    return word_finder.get_word_at(offset)
+
+
+class Worder(object):
+    """A class for finding boundaries of words and expressions
+
+    Note that in these methods, offset should be the index of the
+    character not the index of the character after it.
+    """
+
+    def __init__(self, code, handle_ignores=False):
+        simplified = rope.base.simplify.real_code(code)
+        self.code_finder = _RealFinder(simplified, code)
+        self.handle_ignores = handle_ignores
+        self.code = code
+
+    def _init_ignores(self):
+        ignores = rope.base.simplify.ignored_regions(self.code)
+        self.dumb_finder = _RealFinder(self.code, self.code)
+        self.starts = [ignored[0] for ignored in ignores]
+        self.ends = [ignored[1] for ignored in ignores]
+
+    def _context_call(self, name, offset):
+        if self.handle_ignores:
+            if not hasattr(self, 'starts'):
+                self._init_ignores()
+            start = bisect.bisect(self.starts, offset)
+            if start > 0 and offset < self.ends[start - 1]:
+                return getattr(self.dumb_finder, name)(offset)
+        return getattr(self.code_finder, name)(offset)
+
+    def get_primary_at(self, offset):
+        return self._context_call('get_primary_at', offset)
+
+    def get_word_at(self, offset):
+        return self._context_call('get_word_at', offset)
+
+    def get_primary_range(self, offset):
+        return self._context_call('get_primary_range', offset)
+
+    def get_splitted_primary_before(self, offset):
+        return self._context_call('get_splitted_primary_before', offset)
+
+    def get_word_range(self, offset):
+        return self._context_call('get_word_range', offset)
+
+    def is_function_keyword_parameter(self, offset):
+        return self.code_finder.is_function_keyword_parameter(offset)
+
+    def is_a_class_or_function_name_in_header(self, offset):
+        return self.code_finder.is_a_class_or_function_name_in_header(offset)
+
+    def is_from_statement_module(self, offset):
+        return self.code_finder.is_from_statement_module(offset)
+
+    def is_from_aliased(self, offset):
+        return self.code_finder.is_from_aliased(offset)
+
+    def find_parens_start_from_inside(self, offset):
+        return self.code_finder.find_parens_start_from_inside(offset)
+
+    def is_a_name_after_from_import(self, offset):
+        return self.code_finder.is_a_name_after_from_import(offset)
+
+    def is_from_statement(self, offset):
+        return self.code_finder.is_from_statement(offset)
+
+    def get_from_aliased(self, offset):
+        return self.code_finder.get_from_aliased(offset)
+
+    def is_import_statement(self, offset):
+        return self.code_finder.is_import_statement(offset)
+
+    def is_assigned_here(self, offset):
+        return self.code_finder.is_assigned_here(offset)
+
+    def is_a_function_being_called(self, offset):
+        return self.code_finder.is_a_function_being_called(offset)
+
+    def get_word_parens_range(self, offset):
+        return self.code_finder.get_word_parens_range(offset)
+
+    def is_name_assigned_in_class_body(self, offset):
+        return self.code_finder.is_name_assigned_in_class_body(offset)
+
+    def is_on_function_call_keyword(self, offset):
+        return self.code_finder.is_on_function_call_keyword(offset)
+
+    def _find_parens_start(self, offset):
+        return self.code_finder._find_parens_start(offset)
+
+    def get_parameters(self, first, last):
+        return self.code_finder.get_parameters(first, last)
+
+    def get_from_module(self, offset):
+        return self.code_finder.get_from_module(offset)
+
+    def is_assigned_in_a_tuple_assignment(self, offset):
+        return self.code_finder.is_assigned_in_a_tuple_assignment(offset)
+
+    def get_assignment_type(self, offset):
+        return self.code_finder.get_assignment_type(offset)
+
+    def get_function_and_args_in_header(self, offset):
+        return self.code_finder.get_function_and_args_in_header(offset)
+
+    def get_lambda_and_args(self, offset):
+        return self.code_finder.get_lambda_and_args(offset)
+
+    def find_function_offset(self, offset):
+        return self.code_finder.find_function_offset(offset)
+
+
+class _RealFinder(object):
+
+    def __init__(self, code, raw):
+        self.code = code
+        self.raw = raw
+
+    def _find_word_start(self, offset):
+        current_offset = offset
+        while current_offset >= 0 and self._is_id_char(current_offset):
+            current_offset -= 1
+        return current_offset + 1
+
+    def _find_word_end(self, offset):
+        while offset + 1 < len(self.code) and self._is_id_char(offset + 1):
+            offset += 1
+        return offset
+
+    def _find_last_non_space_char(self, offset):
+        while offset >= 0 and self.code[offset].isspace():
+            if self.code[offset] == '\n':
+                return offset
+            offset -= 1
+        return max(-1, offset)
+
+    def get_word_at(self, offset):
+        offset = self._get_fixed_offset(offset)
+        return self.raw[self._find_word_start(offset):
+                        self._find_word_end(offset) + 1]
+
+    def _get_fixed_offset(self, offset):
+        if offset >= len(self.code):
+            return offset - 1
+        if not self._is_id_char(offset):
+            if offset > 0 and self._is_id_char(offset - 1):
+                return offset - 1
+            if offset < len(self.code) - 1 and self._is_id_char(offset + 1):
+                return offset + 1
+        return offset
+
+    def _is_id_char(self, offset):
+        return self.code[offset].isalnum() or self.code[offset] == '_'
+
+    def _find_string_start(self, offset):
+        kind = self.code[offset]
+        try:
+            return self.code.rindex(kind, 0, offset)
+        except ValueError:
+            return 0
+
+    def _find_parens_start(self, offset):
+        offset = self._find_last_non_space_char(offset - 1)
+        while offset >= 0 and self.code[offset] not in '[({':
+            if self.code[offset] not in ':,':
+                offset = self._find_primary_start(offset)
+            offset = self._find_last_non_space_char(offset - 1)
+        return offset
+
+    def _find_atom_start(self, offset):
+        old_offset = offset
+        if self.code[offset] == '\n':
+            return offset + 1
+        if self.code[offset].isspace():
+            offset = self._find_last_non_space_char(offset)
+        if self.code[offset] in '\'"':
+            return self._find_string_start(offset)
+        if self.code[offset] in ')]}':
+            return self._find_parens_start(offset)
+        if self._is_id_char(offset):
+            return self._find_word_start(offset)
+        return old_offset
+
+    def _find_primary_without_dot_start(self, offset):
+        """It tries to find the undotted primary start
+
+        It is different from `self._get_atom_start()` in that it
+        follows function calls, too; such as in ``f(x)``.
+
+        """
+        last_atom = offset
+        offset = self._find_last_non_space_char(last_atom)
+        while offset > 0 and self.code[offset] in ')]':
+            last_atom = self._find_parens_start(offset)
+            offset = self._find_last_non_space_char(last_atom - 1)
+        if offset >= 0 and (self.code[offset] in '"\'})]' or
+                            self._is_id_char(offset)):
+            atom_start = self._find_atom_start(offset)
+            if not keyword.iskeyword(self.code[atom_start:offset + 1]):
+                return atom_start
+        return last_atom
+
+    def _find_primary_start(self, offset):
+        if offset >= len(self.code):
+            offset = len(self.code) - 1
+        if self.code[offset] != '.':
+            offset = self._find_primary_without_dot_start(offset)
+        else:
+            offset = offset + 1
+        while offset > 0:
+            prev = self._find_last_non_space_char(offset - 1)
+            if offset <= 0 or self.code[prev] != '.':
+                break
+            offset = self._find_primary_without_dot_start(prev - 1)
+            if not self._is_id_char(offset):
+                break
+
+        return offset
+
+    def get_primary_at(self, offset):
+        offset = self._get_fixed_offset(offset)
+        start, end = self.get_primary_range(offset)
+        return self.raw[start:end].strip()
+
+    def get_splitted_primary_before(self, offset):
+        """returns expression, starting, starting_offset
+
+        This function is used in `rope.codeassist.assist` function.
+        """
+        if offset == 0:
+            return ('', '', 0)
+        end = offset - 1
+        word_start = self._find_atom_start(end)
+        real_start = self._find_primary_start(end)
+        if self.code[word_start:offset].strip() == '':
+            word_start = end
+        if self.code[end].isspace():
+            word_start = end
+        if self.code[real_start:word_start].strip() == '':
+            real_start = word_start
+        if real_start == word_start == end and not self._is_id_char(end):
+            return ('', '', offset)
+        if real_start == word_start:
+            return ('', self.raw[word_start:offset], word_start)
+        else:
+            if self.code[end] == '.':
+                return (self.raw[real_start:end], '', offset)
+            last_dot_position = word_start
+            if self.code[word_start] != '.':
+                last_dot_position = self._find_last_non_space_char(word_start - 1)
+            last_char_position = self._find_last_non_space_char(last_dot_position - 1)
+            if self.code[word_start].isspace():
+                word_start = offset
+            return (self.raw[real_start:last_char_position + 1],
+                    self.raw[word_start:offset], word_start)
+
+    def _get_line_start(self, offset):
+        try:
+            return self.code.rindex('\n', 0, offset + 1)
+        except ValueError:
+            return 0
+
+    def _get_line_end(self, offset):
+        try:
+            return self.code.index('\n', offset)
+        except ValueError:
+            return len(self.code)
+
+    def is_name_assigned_in_class_body(self, offset):
+        word_start = self._find_word_start(offset - 1)
+        word_end = self._find_word_end(offset) + 1
+        if '.' in self.code[word_start:word_end]:
+            return False
+        line_start = self._get_line_start(word_start)
+        line = self.code[line_start:word_start].strip()
+        return not line and self.get_assignment_type(offset) == '='
+
+    def is_a_class_or_function_name_in_header(self, offset):
+        word_start = self._find_word_start(offset - 1)
+        line_start = self._get_line_start(word_start)
+        prev_word = self.code[line_start:word_start].strip()
+        return prev_word in ['def', 'class']
+
+    def _find_first_non_space_char(self, offset):
+        if offset >= len(self.code):
+            return len(self.code)
+        while offset < len(self.code) and self.code[offset].isspace():
+            if self.code[offset] == '\n':
+                return offset
+            offset += 1
+        return offset
+
+    def is_a_function_being_called(self, offset):
+        word_end = self._find_word_end(offset) + 1
+        next_char = self._find_first_non_space_char(word_end)
+        return next_char < len(self.code) and \
+               self.code[next_char] == '(' and \
+               not self.is_a_class_or_function_name_in_header(offset)
+
+    def _find_import_end(self, start):
+        return self._get_line_end(start)
+
+    def is_import_statement(self, offset):
+        try:
+            last_import = self.code.rindex('import ', 0, offset)
+        except ValueError:
+            return False
+        return self._find_import_end(last_import + 7) >= offset
+
+    def is_from_statement(self, offset):
+        try:
+            last_from = self.code.rindex('from ', 0, offset)
+            from_import = self.code.index(' import ', last_from)
+            from_names = from_import + 8
+        except ValueError:
+            return False
+        from_names = self._find_first_non_space_char(from_names)
+        return self._find_import_end(from_names) >= offset
+
+    def is_from_statement_module(self, offset):
+        if offset >= len(self.code) - 1:
+            return False
+        stmt_start = self._find_primary_start(offset)
+        line_start = self._get_line_start(stmt_start)
+        prev_word = self.code[line_start:stmt_start].strip()
+        return prev_word == 'from'
+
+    def is_a_name_after_from_import(self, offset):
+        try:
+            line_start = self._get_line_start(offset)
+            last_from = self.code.rindex('from ', line_start, offset)
+            from_import = self.code.index(' import ', last_from)
+            from_names = from_import + 8
+        except ValueError:
+            return False
+        if from_names - 1 > offset:
+            return False
+        return self._find_import_end(from_names) >= offset
+
+    def get_from_module(self, offset):
+        try:
+            last_from = self.code.rindex('from ', 0, offset)
+            import_offset = self.code.index(' import ', last_from)
+            end = self._find_last_non_space_char(import_offset)
+            return self.get_primary_at(end)
+        except ValueError:
+            pass
+
+    def is_from_aliased(self, offset):
+        if not self.is_a_name_after_from_import(offset):
+            return False
+        try:
+            end = self._find_word_end(offset)
+            as_end = min(self._find_word_end(end + 1), len(self.code))
+            as_start = self._find_word_start(as_end)
+            if self.code[as_start:as_end + 1] == 'as':
+                return True
+        except ValueError:
+            return False
+
+    def get_from_aliased(self, offset):
+        try:
+            end = self._find_word_end(offset)
+            as_ = self._find_word_end(end + 1)
+            alias = self._find_word_end(as_ + 1)
+            start = self._find_word_start(alias)
+            return self.raw[start:alias + 1]
+        except ValueError:
+            pass
+
+    def is_function_keyword_parameter(self, offset):
+        word_end = self._find_word_end(offset)
+        if word_end + 1 == len(self.code):
+            return False
+        next_char = self._find_first_non_space_char(word_end + 1)
+        equals = self.code[next_char:next_char + 2]
+        if equals == '==' or not equals.startswith('='):
+            return False
+        word_start = self._find_word_start(offset)
+        prev_char = self._find_last_non_space_char(word_start - 1)
+        return prev_char - 1 >= 0 and self.code[prev_char] in ',('
+
+    def is_on_function_call_keyword(self, offset):
+        stop = self._get_line_start(offset)
+        if self._is_id_char(offset):
+            offset = self._find_word_start(offset) - 1
+        offset = self._find_last_non_space_char(offset)
+        if offset <= stop or self.code[offset] not in '(,':
+            return False
+        parens_start = self.find_parens_start_from_inside(offset)
+        return stop < parens_start
+
+    def find_parens_start_from_inside(self, offset):
+        stop = self._get_line_start(offset)
+        opens = 1
+        while offset > stop:
+            if self.code[offset] == '(':
+                break
+            if self.code[offset] != ',':
+                offset = self._find_primary_start(offset)
+            offset -= 1
+        return max(stop, offset)
+
+    def is_assigned_here(self, offset):
+        return self.get_assignment_type(offset) is not None
+
+    def get_assignment_type(self, offset):
+        # XXX: does not handle tuple assignments
+        word_end = self._find_word_end(offset)
+        next_char = self._find_first_non_space_char(word_end + 1)
+        single = self.code[next_char:next_char + 1]
+        double = self.code[next_char:next_char + 2]
+        triple = self.code[next_char:next_char + 3]
+        if double not in ('==', '<=', '>=', '!='):
+            for op in [single, double, triple]:
+                if op.endswith('='):
+                    return op
+
+    def get_primary_range(self, offset):
+        start = self._find_primary_start(offset)
+        end = self._find_word_end(offset) + 1
+        return (start, end)
+
+    def get_word_range(self, offset):
+        offset = max(0, offset)
+        start = self._find_word_start(offset)
+        end = self._find_word_end(offset) + 1
+        return (start, end)
+
+    def get_word_parens_range(self, offset, opening='(', closing=')'):
+        end = self._find_word_end(offset)
+        start_parens = self.code.index(opening, end)
+        index = start_parens
+        open_count = 0
+        while index < len(self.code):
+            if self.code[index] == opening:
+                open_count += 1
+            if self.code[index] == closing:
+                open_count -= 1
+            if open_count == 0:
+                return (start_parens, index + 1)
+            index += 1
+        return (start_parens, index)
+
+    def get_parameters(self, first, last):
+        keywords = []
+        args = []
+        current = self._find_last_non_space_char(last - 1)
+        while current > first:
+            primary_start = current
+            current = self._find_primary_start(current)
+            while current != first and self.code[current] not in '=,':
+                current = self._find_last_non_space_char(current - 1)
+            primary = self.raw[current + 1:primary_start + 1].strip()
+            if self.code[current] == '=':
+                primary_start = current - 1
+                current -= 1
+                while current != first and self.code[current] not in ',':
+                    current = self._find_last_non_space_char(current - 1)
+                param_name = self.raw[current + 1:primary_start + 1].strip()
+                keywords.append((param_name, primary))
+            else:
+                args.append(primary)
+            current = self._find_last_non_space_char(current - 1)
+        args.reverse()
+        keywords.reverse()
+        return args, keywords
+
+    def is_assigned_in_a_tuple_assignment(self, offset):
+        start = self._get_line_start(offset)
+        end = self._get_line_end(offset)
+        primary_start = self._find_primary_start(offset)
+        primary_end = self._find_word_end(offset)
+
+        prev_char_offset = self._find_last_non_space_char(primary_start - 1)
+        next_char_offset = self._find_first_non_space_char(primary_end + 1)
+        next_char = prev_char = ''
+        if prev_char_offset >= start:
+            prev_char = self.code[prev_char_offset]
+        if next_char_offset < end:
+            next_char = self.code[next_char_offset]
+        try:
+            equals_offset = self.code.index('=', start, end)
+        except ValueError:
+            return False
+        if prev_char not in '(,' and next_char not in ',)':
+            return False
+        parens_start = self.find_parens_start_from_inside(offset)
+        # XXX: only handling (x, y) = value
+        return offset < equals_offset and \
+               self.code[start:parens_start].strip() == ''
+
+    def get_function_and_args_in_header(self, offset):
+        offset = self.find_function_offset(offset)
+        lparens, rparens = self.get_word_parens_range(offset)
+        return self.raw[offset:rparens + 1]
+
+    def find_function_offset(self, offset, definition='def '):
+        while True:
+            offset = self.code.index(definition, offset)
+            if offset == 0 or not self._is_id_char(offset - 1):
+                break
+            offset += 1
+        def_ = offset + 4
+        return self._find_first_non_space_char(def_)
+
+    def get_lambda_and_args(self, offset):
+        offset = self.find_function_offset(offset, definition = 'lambda ')
+        lparens, rparens = self.get_word_parens_range(offset, opening=' ', closing=':')
+        return self.raw[offset:rparens + 1]
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/contrib/__init__.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,7 @@
+"""rope IDE tools package
+
+This package contains modules that can be used in IDEs
+but do not depend on the UI.  So these modules will be used
+by `rope.ui` modules.
+
+"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/contrib/autoimport.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,217 @@
+import re
+
+from rope.base import (exceptions, pynames, resourceobserver,
+                       taskhandle, pyobjects, builtins, resources)
+from rope.refactor import importutils
+
+
+class AutoImport(object):
+    """A class for finding the module that provides a name
+
+    This class maintains a cache of global names in python modules.
+    Note that this cache is not accurate and might be out of date.
+
+    """
+
+    def __init__(self, project, observe=True, underlined=False):
+        """Construct an AutoImport object
+
+        If `observe` is `True`, listen for project changes and update
+        the cache.
+
+        If `underlined` is `True`, underlined names are cached, too.
+        """
+        self.project = project
+        self.underlined = underlined
+        self.names = project.data_files.read_data('globalnames')
+        if self.names is None:
+            self.names = {}
+        project.data_files.add_write_hook(self._write)
+        # XXX: using a filtered observer
+        observer = resourceobserver.ResourceObserver(
+            changed=self._changed, moved=self._moved, removed=self._removed)
+        if observe:
+            project.add_observer(observer)
+
+    def import_assist(self, starting):
+        """Return a list of ``(name, module)`` tuples
+
+        This function tries to find modules that have a global name
+        that starts with `starting`.
+        """
+        # XXX: breaking if gave up! use generators
+        result = []
+        for module in self.names:
+            for global_name in self.names[module]:
+                if global_name.startswith(starting):
+                    result.append((global_name, module))
+        return result
+
+    def get_modules(self, name):
+        """Return the list of modules that have global `name`"""
+        result = []
+        for module in self.names:
+            if name in self.names[module]:
+                result.append(module)
+        return result
+
+    def get_all_names(self):
+        """Return the list of all cached global names"""
+        result = set()
+        for module in self.names:
+            result.update(set(self.names[module]))
+        return result
+
+    def get_name_locations(self, name):
+        """Return a list of ``(resource, lineno)`` tuples"""
+        result = []
+        pycore = self.project.pycore
+        for module in self.names:
+            if name in self.names[module]:
+                try:
+                    pymodule = pycore.get_module(module)
+                    if name in pymodule:
+                        pyname = pymodule[name]
+                        module, lineno = pyname.get_definition_location()
+                        if module is not None:
+                            resource = module.get_module().get_resource()
+                            if resource is not None and lineno is not None:
+                                result.append((resource, lineno))
+                except exceptions.ModuleNotFoundError:
+                    pass
+        return result
+
+    def generate_cache(self, resources=None, underlined=None,
+                       task_handle=taskhandle.NullTaskHandle()):
+        """Generate global name cache for project files
+
+        If `resources` is a list of `rope.base.resource.File`\s, only
+        those files are searched; otherwise all python modules in the
+        project are cached.
+
+        """
+        if resources is None:
+            resources = self.project.pycore.get_python_files()
+        job_set = task_handle.create_jobset(
+            'Generatig autoimport cache', len(resources))
+        for file in resources:
+            job_set.started_job('Working on <%s>' % file.path)
+            self.update_resource(file, underlined)
+            job_set.finished_job()
+
+    def generate_modules_cache(self, modules, underlined=None,
+                               task_handle=taskhandle.NullTaskHandle()):
+        """Generate global name cache for modules listed in `modules`"""
+        job_set = task_handle.create_jobset(
+            'Generatig autoimport cache for modules', len(modules))
+        for modname in modules:
+            job_set.started_job('Working on <%s>' % modname)
+            if modname.endswith('.*'):
+                mod = self.project.pycore.find_module(modname[:-2])
+                if mod:
+                    for sub in submodules(mod):
+                        self.update_resource(sub, underlined)
+            else:
+                self.update_module(modname, underlined)
+            job_set.finished_job()
+
+    def clear_cache(self):
+        """Clear all entries in global-name cache
+
+        It might be a good idea to use this function before
+        regenerating global names.
+
+        """
+        self.names.clear()
+
+    def find_insertion_line(self, code):
+        """Guess at what line the new import should be inserted"""
+        match = re.search(r'^(def|class)\s+', code)
+        if match is not None:
+            code = code[:match.start()]
+        try:
+            pymodule = self.project.pycore.get_string_module(code)
+        except exceptions.ModuleSyntaxError:
+            return 1
+        testmodname = '__rope_testmodule_rope'
+        importinfo = importutils.NormalImport(((testmodname, None),))
+        module_imports = importutils.get_module_imports(
+            self.project.pycore, pymodule)
+        module_imports.add_import(importinfo)
+        code = module_imports.get_changed_source()
+        offset = code.index(testmodname)
+        lineno = code.count('\n', 0, offset) + 1
+        return lineno
+
+    def update_resource(self, resource, underlined=None):
+        """Update the cache for global names in `resource`"""
+        try:
+            pymodule = self.project.pycore.resource_to_pyobject(resource)
+            modname = self._module_name(resource)
+            self._add_names(pymodule, modname, underlined)
+        except exceptions.ModuleSyntaxError:
+            pass
+
+    def update_module(self, modname, underlined=None):
+        """Update the cache for global names in `modname` module
+
+        `modname` is the name of a module.
+        """
+        try:
+            pymodule = self.project.pycore.get_module(modname)
+            self._add_names(pymodule, modname, underlined)
+        except exceptions.ModuleNotFoundError:
+            pass
+
+    def _module_name(self, resource):
+        return self.project.pycore.modname(resource)
+
+    def _add_names(self, pymodule, modname, underlined):
+        if underlined is None:
+            underlined = self.underlined
+        globals = []
+        if isinstance(pymodule, pyobjects.PyDefinedObject):
+            attributes = pymodule._get_structural_attributes()
+        else:
+            attributes = pymodule.get_attributes()
+        for name, pyname in attributes.items():
+            if not underlined and name.startswith('_'):
+                continue
+            if isinstance(pyname, (pynames.AssignedName, pynames.DefinedName)):
+                globals.append(name)
+            if isinstance(pymodule, builtins.BuiltinModule):
+                globals.append(name)
+        self.names[modname] = globals
+
+    def _write(self):
+        self.project.data_files.write_data('globalnames', self.names)
+
+    def _changed(self, resource):
+        if not resource.is_folder():
+            self.update_resource(resource)
+
+    def _moved(self, resource, newresource):
+        if not resource.is_folder():
+            modname = self._module_name(resource)
+            if modname in self.names:
+                del self.names[modname]
+            self.update_resource(newresource)
+
+    def _removed(self, resource):
+        if not resource.is_folder():
+            modname = self._module_name(resource)
+            if modname in self.names:
+                del self.names[modname]
+
+
+def submodules(mod):
+    if isinstance(mod, resources.File):
+        if mod.name.endswith('.py') and mod.name != '__init__.py':
+            return set([mod])
+        return set()
+    if not mod.has_child('__init__.py'):
+        return set()
+    result = set([mod])
+    for child in mod.get_children():
+        result |= submodules(child)
+    return result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/contrib/changestack.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,52 @@
+"""For performing many refactorings as a single command
+
+`changestack` module can be used to perform many refactorings on top
+of each other as one bigger command.  It can be used like::
+
+  stack = ChangeStack(project, 'my big command')
+
+  #..
+  stack.push(refactoring1.get_changes())
+  #..
+  stack.push(refactoring2.get_changes())
+  #..
+  stack.push(refactoringX.get_changes())
+
+  stack.pop_all()
+  changes = stack.merged()
+
+Now `changes` can be previewed or performed as before.
+"""
+
+from rope.base import change
+
+
+class ChangeStack(object):
+
+    def __init__(self, project, description='merged changes'):
+        self.project = project
+        self.description = description
+        self.stack = []
+
+    def push(self, changes):
+        self.stack.append(changes)
+        self.project.do(changes)
+
+    def pop_all(self):
+        for i in range(len(self.stack)):
+            self.project.history.undo(drop=True)
+
+    def merged(self):
+        result = change.ChangeSet(self.description)
+        for changes in self.stack:
+            for c in self._basic_changes(changes):
+                result.add_change(c)
+        return result
+
+    def _basic_changes(self, changes):
+        if isinstance(changes, change.ChangeSet):
+            for child in changes.changes:
+                for atom in self._basic_changes(child):
+                    yield atom
+        else:
+            yield changes
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/contrib/codeassist.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,647 @@
+import keyword
+import sys
+import warnings
+
+import rope.base.codeanalyze
+import rope.base.evaluate
+from rope.base import pyobjects, pyobjectsdef, pynames, builtins, exceptions, worder
+from rope.base.codeanalyze import SourceLinesAdapter
+from rope.contrib import fixsyntax
+from rope.refactor import functionutils
+
+
+def code_assist(project, source_code, offset, resource=None,
+                templates=None, maxfixes=1, later_locals=True):
+    """Return python code completions as a list of `CodeAssistProposal`\s
+
+    `resource` is a `rope.base.resources.Resource` object.  If
+    provided, relative imports are handled.
+
+    `maxfixes` is the maximum number of errors to fix if the code has
+    errors in it.
+
+    If `later_locals` is `False` names defined in this scope and after
+    this line is ignored.
+
+    """
+    if templates is not None:
+        warnings.warn('Codeassist no longer supports templates',
+                      DeprecationWarning, stacklevel=2)
+    assist = _PythonCodeAssist(
+        project, source_code, offset, resource=resource,
+        maxfixes=maxfixes, later_locals=later_locals)
+    return assist()
+
+
+def starting_offset(source_code, offset):
+    """Return the offset in which the completion should be inserted
+
+    Usually code assist proposals should be inserted like::
+
+        completion = proposal.name
+        result = (source_code[:starting_offset] +
+                  completion + source_code[offset:])
+
+    Where starting_offset is the offset returned by this function.
+
+    """
+    word_finder = worder.Worder(source_code, True)
+    expression, starting, starting_offset = \
+        word_finder.get_splitted_primary_before(offset)
+    return starting_offset
+
+
+def get_doc(project, source_code, offset, resource=None, maxfixes=1):
+    """Get the pydoc"""
+    fixer = fixsyntax.FixSyntax(project.pycore, source_code,
+                                resource, maxfixes)
+    pymodule = fixer.get_pymodule()
+    pyname = fixer.pyname_at(offset)
+    if pyname is None:
+        return None
+    pyobject = pyname.get_object()
+    return PyDocExtractor().get_doc(pyobject)
+
+
+def get_calltip(project, source_code, offset, resource=None,
+                maxfixes=1, ignore_unknown=False, remove_self=False):
+    """Get the calltip of a function
+
+    The format of the returned string is
+    ``module_name.holding_scope_names.function_name(arguments)``.  For
+    classes `__init__()` and for normal objects `__call__()` function
+    is used.
+
+    Note that the offset is on the function itself *not* after the its
+    open parenthesis.  (Actually it used to be the other way but it
+    was easily confused when string literals were involved.  So I
+    decided it is better for it not to try to be too clever when it
+    cannot be clever enough).  You can use a simple search like::
+
+        offset = source_code.rindex('(', 0, offset) - 1
+
+    to handle simple situations.
+
+    If `ignore_unknown` is `True`, `None` is returned for functions
+    without source-code like builtins and extensions.
+
+    If `remove_self` is `True`, the first parameter whose name is self
+    will be removed for methods.
+    """
+    fixer = fixsyntax.FixSyntax(project.pycore, source_code,
+                                resource, maxfixes)
+    pymodule = fixer.get_pymodule()
+    pyname = fixer.pyname_at(offset)
+    if pyname is None:
+        return None
+    pyobject = pyname.get_object()
+    return PyDocExtractor().get_calltip(pyobject, ignore_unknown, remove_self)
+
+
+def get_definition_location(project, source_code, offset,
+                            resource=None, maxfixes=1):
+    """Return the definition location of the python name at `offset`
+
+    Return a (`rope.base.resources.Resource`, lineno) tuple.  If no
+    `resource` is given and the definition is inside the same module,
+    the first element of the returned tuple would be `None`.  If the
+    location cannot be determined ``(None, None)`` is returned.
+
+    """
+    fixer = fixsyntax.FixSyntax(project.pycore, source_code,
+                                resource, maxfixes)
+    pymodule = fixer.get_pymodule()
+    pyname = fixer.pyname_at(offset)
+    if pyname is not None:
+        module, lineno = pyname.get_definition_location()
+        if module is not None:
+            return module.get_module().get_resource(), lineno
+    return (None, None)
+
+
+def find_occurrences(*args, **kwds):
+    import rope.contrib.findit
+    warnings.warn('Use `rope.contrib.findit.find_occurrences()` instead',
+                  DeprecationWarning, stacklevel=2)
+    return rope.contrib.findit.find_occurrences(*args, **kwds)
+
+
+class CompletionProposal(object):
+    """A completion proposal
+
+    The `scope` instance variable shows where proposed name came from
+    and can be 'global', 'local', 'builtin', 'attribute', 'keyword',
+    'imported', 'parameter_keyword'.
+
+    The `type` instance variable shows the approximate type of the
+    proposed object and can be 'instance', 'class', 'function', 'module',
+    and `None`.
+
+    All possible relations between proposal's `scope` and `type` are shown
+    in the table below (different scopes in rows and types in columns):
+
+                      | instance | class | function | module | None
+                local |    +     |   +   |    +     |   +    |
+               global |    +     |   +   |    +     |   +    |
+              builtin |    +     |   +   |    +     |        |
+            attribute |    +     |   +   |    +     |   +    |
+             imported |    +     |   +   |    +     |   +    |
+              keyword |          |       |          |        |  +
+    parameter_keyword |          |       |          |        |  +
+
+    """
+
+    def __init__(self, name, scope, pyname=None):
+        self.name = name
+        self.pyname = pyname
+        self.scope = self._get_scope(scope)
+
+    def __str__(self):
+        return '%s (%s, %s)' % (self.name, self.scope, self.type)
+
+    def __repr__(self):
+        return str(self)
+
+    @property
+    def parameters(self):
+        """The names of the parameters the function takes.
+
+        Returns None if this completion is not a function.
+        """
+        pyname = self.pyname
+        if isinstance(pyname, pynames.ImportedName):
+            pyname = pyname._get_imported_pyname()
+        if isinstance(pyname, pynames.DefinedName):
+            pyobject = pyname.get_object()
+            if isinstance(pyobject, pyobjects.AbstractFunction):
+                return pyobject.get_param_names()
+
+    @property
+    def type(self):
+        pyname = self.pyname
+        if isinstance(pyname, builtins.BuiltinName):
+            pyobject = pyname.get_object()
+            if isinstance(pyobject, builtins.BuiltinFunction):
+                return 'function'
+            elif isinstance(pyobject, builtins.BuiltinClass):
+                clsobj = pyobject.builtin
+                return 'class'
+            elif isinstance(pyobject, builtins.BuiltinObject) or \
+                 isinstance(pyobject, builtins.BuiltinName):
+                return 'instance'
+        elif isinstance(pyname, pynames.ImportedModule):
+            return 'module'
+        elif isinstance(pyname, pynames.ImportedName) or \
+           isinstance(pyname, pynames.DefinedName):
+            pyobject = pyname.get_object()
+            if isinstance(pyobject, pyobjects.AbstractFunction):
+                return 'function'
+            if isinstance(pyobject, pyobjects.AbstractClass):
+                return 'class'
+        return 'instance'
+
+    def _get_scope(self, scope):
+        if isinstance(self.pyname, builtins.BuiltinName):
+            return 'builtin'
+        if isinstance(self.pyname, pynames.ImportedModule) or \
+           isinstance(self.pyname, pynames.ImportedName):
+            return 'imported'
+        return scope
+
+    def get_doc(self):
+        """Get the proposed object's docstring.
+
+        Returns None if it can not be get.
+        """
+        if not self.pyname:
+            return None
+        pyobject = self.pyname.get_object()
+        if not hasattr(pyobject, 'get_doc'):
+            return None
+        return self.pyname.get_object().get_doc()
+
+    @property
+    def kind(self):
+        warnings.warn("the proposal's `kind` property is deprecated, " \
+                      "use `scope` instead")
+        return self.scope
+
+
+# leaved for backward compatibility
+CodeAssistProposal = CompletionProposal
+
+
+class NamedParamProposal(CompletionProposal):
+    """A parameter keyword completion proposal
+
+    Holds reference to ``_function`` -- the function which
+    parameter ``name`` belongs to. This allows to determine
+    default value for this parameter.
+    """
+    def __init__(self, name, function):
+        self.argname = name
+        name = '%s=' % name
+        super(NamedParamProposal, self).__init__(name, 'parameter_keyword')
+        self._function = function
+
+    def get_default(self):
+        """Get a string representation of a param's default value.
+
+        Returns None if there is no default value for this param.
+        """
+        definfo = functionutils.DefinitionInfo.read(self._function)
+        for arg, default in definfo.args_with_defaults:
+            if self.argname == arg:
+                return default
+        return None
+
+
+def sorted_proposals(proposals, scopepref=None, typepref=None):
+    """Sort a list of proposals
+
+    Return a sorted list of the given `CodeAssistProposal`\s.
+
+    `scopepref` can be a list of proposal scopes.  Defaults to
+    ``['parameter_keyword', 'local', 'global', 'imported',
+    'attribute', 'builtin', 'keyword']``.
+
+    `typepref` can be a list of proposal types.  Defaults to
+    ``['class', 'function', 'instance', 'module', None]``.
+    (`None` stands for completions with no type like keywords.)
+    """
+    sorter = _ProposalSorter(proposals, scopepref, typepref)
+    return sorter.get_sorted_proposal_list()
+
+
+def starting_expression(source_code, offset):
+    """Return the expression to complete"""
+    word_finder = worder.Worder(source_code, True)
+    expression, starting, starting_offset = \
+        word_finder.get_splitted_primary_before(offset)
+    if expression:
+        return expression + '.' + starting
+    return starting
+
+
+def default_templates():
+    warnings.warn('default_templates() is deprecated.',
+                  DeprecationWarning, stacklevel=2)
+    return {}
+
+
+class _PythonCodeAssist(object):
+
+    def __init__(self, project, source_code, offset, resource=None,
+                 maxfixes=1, later_locals=True):
+        self.project = project
+        self.pycore = self.project.pycore
+        self.code = source_code
+        self.resource = resource
+        self.maxfixes = maxfixes
+        self.later_locals = later_locals
+        self.word_finder = worder.Worder(source_code, True)
+        self.expression, self.starting, self.offset = \
+            self.word_finder.get_splitted_primary_before(offset)
+
+    keywords = keyword.kwlist
+
+    def _find_starting_offset(self, source_code, offset):
+        current_offset = offset - 1
+        while current_offset >= 0 and (source_code[current_offset].isalnum() or
+                                       source_code[current_offset] in '_'):
+            current_offset -= 1;
+        return current_offset + 1
+
+    def _matching_keywords(self, starting):
+        result = []
+        for kw in self.keywords:
+            if kw.startswith(starting):
+                result.append(CompletionProposal(kw, 'keyword'))
+        return result
+
+    def __call__(self):
+        if self.offset > len(self.code):
+            return []
+        completions = list(self._code_completions().values())
+        if self.expression.strip() == '' and self.starting.strip() != '':
+            completions.extend(self._matching_keywords(self.starting))
+        return completions
+
+    def _dotted_completions(self, module_scope, holding_scope):
+        result = {}
+        found_pyname = rope.base.evaluate.eval_str(holding_scope,
+                                                   self.expression)
+        if found_pyname is not None:
+            element = found_pyname.get_object()
+            compl_scope = 'attribute'
+            if isinstance(element, (pyobjectsdef.PyModule,
+                                    pyobjectsdef.PyPackage)):
+                compl_scope = 'imported'
+            for name, pyname in element.get_attributes().items():
+                if name.startswith(self.starting):
+                    result[name] = CompletionProposal(name, compl_scope, pyname)
+        return result
+
+    def _undotted_completions(self, scope, result, lineno=None):
+        if scope.parent != None:
+            self._undotted_completions(scope.parent, result)
+        if lineno is None:
+            names = scope.get_propagated_names()
+        else:
+            names = scope.get_names()
+        for name, pyname in names.items():
+            if name.startswith(self.starting):
+                compl_scope = 'local'
+                if scope.get_kind() == 'Module':
+                    compl_scope = 'global'
+                if lineno is None or self.later_locals or \
+                   not self._is_defined_after(scope, pyname, lineno):
+                    result[name] = CompletionProposal(name, compl_scope,
+                                                      pyname)
+
+    def _from_import_completions(self, pymodule):
+        module_name = self.word_finder.get_from_module(self.offset)
+        if module_name is None:
+            return {}
+        pymodule = self._find_module(pymodule, module_name)
+        result = {}
+        for name in pymodule:
+            if name.startswith(self.starting):
+                result[name] = CompletionProposal(name, scope='global',
+                                                  pyname=pymodule[name])
+        return result
+
+    def _find_module(self, pymodule, module_name):
+        dots = 0
+        while module_name[dots] == '.':
+            dots += 1
+        pyname = pynames.ImportedModule(pymodule,
+                                        module_name[dots:], dots)
+        return pyname.get_object()
+
+    def _is_defined_after(self, scope, pyname, lineno):
+        location = pyname.get_definition_location()
+        if location is not None and location[1] is not None:
+            if location[0] == scope.pyobject.get_module() and \
+               lineno <= location[1] <= scope.get_end():
+                return True
+
+    def _code_completions(self):
+        lineno = self.code.count('\n', 0, self.offset) + 1
+        fixer = fixsyntax.FixSyntax(self.pycore, self.code,
+                                    self.resource, self.maxfixes)
+        pymodule = fixer.get_pymodule()
+        module_scope = pymodule.get_scope()
+        code = pymodule.source_code
+        lines = code.split('\n')
+        result = {}
+        start = fixsyntax._logical_start(lines, lineno)
+        indents = fixsyntax._get_line_indents(lines[start - 1])
+        inner_scope = module_scope.get_inner_scope_for_line(start, indents)
+        if self.word_finder.is_a_name_after_from_import(self.offset):
+            return self._from_import_completions(pymodule)
+        if self.expression.strip() != '':
+            result.update(self._dotted_completions(module_scope, inner_scope))
+        else:
+            result.update(self._keyword_parameters(module_scope.pyobject,
+                                                   inner_scope))
+            self._undotted_completions(inner_scope, result, lineno=lineno)
+        return result
+
+    def _keyword_parameters(self, pymodule, scope):
+        offset = self.offset
+        if offset == 0:
+            return {}
+        word_finder = worder.Worder(self.code, True)
+        lines = SourceLinesAdapter(self.code)
+        lineno = lines.get_line_number(offset)
+        if word_finder.is_on_function_call_keyword(offset - 1):
+            name_finder = rope.base.evaluate.ScopeNameFinder(pymodule)
+            function_parens = word_finder.\
+                find_parens_start_from_inside(offset - 1)
+            primary = word_finder.get_primary_at(function_parens - 1)
+            try:
+                function_pyname = rope.base.evaluate.\
+                    eval_str(scope, primary)
+            except exceptions.BadIdentifierError, e:
+                return {}
+            if function_pyname is not None:
+                pyobject = function_pyname.get_object()
+                if isinstance(pyobject, pyobjects.AbstractFunction):
+                    pass
+                elif isinstance(pyobject, pyobjects.AbstractClass) and \
+                     '__init__' in pyobject:
+                    pyobject = pyobject['__init__'].get_object()
+                elif '__call__' in pyobject:
+                    pyobject = pyobject['__call__'].get_object()
+                if isinstance(pyobject, pyobjects.AbstractFunction):
+                    param_names = []
+                    param_names.extend(
+                        pyobject.get_param_names(special_args=False))
+                    result = {}
+                    for name in param_names:
+                        if name.startswith(self.starting):
+                            result[name + '='] = NamedParamProposal(
+                                name, pyobject
+                            )
+                    return result
+        return {}
+
+
+class _ProposalSorter(object):
+    """Sort a list of code assist proposals"""
+
+    def __init__(self, code_assist_proposals, scopepref=None, typepref=None):
+        self.proposals = code_assist_proposals
+        if scopepref is None:
+            scopepref = ['parameter_keyword', 'local', 'global', 'imported',
+                        'attribute', 'builtin', 'keyword']
+        self.scopepref = scopepref
+        if typepref is None:
+            typepref = ['class', 'function', 'instance', 'module', None]
+        self.typerank = dict((type, index)
+                              for index, type in enumerate(typepref))
+
+    def get_sorted_proposal_list(self):
+        """Return a list of `CodeAssistProposal`"""
+        proposals = {}
+        for proposal in self.proposals:
+            proposals.setdefault(proposal.scope, []).append(proposal)
+        result = []
+        for scope in self.scopepref:
+            scope_proposals = proposals.get(scope, [])
+            scope_proposals = [proposal for proposal in scope_proposals
+                              if proposal.type in self.typerank]
+            scope_proposals.sort(self._proposal_cmp)
+            result.extend(scope_proposals)
+        return result
+
+    def _proposal_cmp(self, proposal1, proposal2):
+        if proposal1.type != proposal2.type:
+            return cmp(self.typerank.get(proposal1.type, 100),
+                       self.typerank.get(proposal2.type, 100))
+        return self._compare_underlined_names(proposal1.name,
+                                              proposal2.name)
+
+    def _compare_underlined_names(self, name1, name2):
+        def underline_count(name):
+            result = 0
+            while result < len(name) and name[result] == '_':
+                result += 1
+            return result
+        underline_count1 = underline_count(name1)
+        underline_count2 = underline_count(name2)
+        if underline_count1 != underline_count2:
+            return cmp(underline_count1, underline_count2)
+        return cmp(name1, name2)
+
+
+class PyDocExtractor(object):
+
+    def get_doc(self, pyobject):
+        if isinstance(pyobject, pyobjects.AbstractFunction):
+            return self._get_function_docstring(pyobject)
+        elif isinstance(pyobject, pyobjects.AbstractClass):
+            return self._get_class_docstring(pyobject)
+        elif isinstance(pyobject, pyobjects.AbstractModule):
+            return self._trim_docstring(pyobject.get_doc())
+        return None
+
+    def get_calltip(self, pyobject, ignore_unknown=False, remove_self=False):
+        try:
+            if isinstance(pyobject, pyobjects.AbstractClass):
+                pyobject = pyobject['__init__'].get_object()
+            if not isinstance(pyobject, pyobjects.AbstractFunction):
+                pyobject = pyobject['__call__'].get_object()
+        except exceptions.AttributeNotFoundError:
+            return None
+        if ignore_unknown and not isinstance(pyobject, pyobjects.PyFunction):
+            return
+        if isinstance(pyobject, pyobjects.AbstractFunction):
+            result = self._get_function_signature(pyobject, add_module=True)
+            if remove_self and self._is_method(pyobject):
+                return result.replace('(self)', '()').replace('(self, ', '(')
+            return result
+
+    def _get_class_docstring(self, pyclass):
+        contents = self._trim_docstring(pyclass.get_doc(), 2)
+        supers = [super.get_name() for super in pyclass.get_superclasses()]
+        doc = 'class %s(%s):\n\n' % (pyclass.get_name(), ', '.join(supers)) + contents
+
+        if '__init__' in pyclass:
+            init = pyclass['__init__'].get_object()
+            if isinstance(init, pyobjects.AbstractFunction):
+                doc += '\n\n' + self._get_single_function_docstring(init)
+        return doc
+
+    def _get_function_docstring(self, pyfunction):
+        functions = [pyfunction]
+        if self._is_method(pyfunction):
+            functions.extend(self._get_super_methods(pyfunction.parent,
+                                                     pyfunction.get_name()))
+        return '\n\n'.join([self._get_single_function_docstring(function)
+                            for function in functions])
+
+    def _is_method(self, pyfunction):
+        return isinstance(pyfunction, pyobjects.PyFunction) and \
+               isinstance(pyfunction.parent, pyobjects.PyClass)
+
+    def _get_single_function_docstring(self, pyfunction):
+        signature = self._get_function_signature(pyfunction)
+        docs = self._trim_docstring(pyfunction.get_doc(), indents=2)
+        return signature + ':\n\n' + docs
+
+    def _get_super_methods(self, pyclass, name):
+        result = []
+        for super_class in pyclass.get_superclasses():
+            if name in super_class:
+                function = super_class[name].get_object()
+                if isinstance(function, pyobjects.AbstractFunction):
+                    result.append(function)
+            result.extend(self._get_super_methods(super_class, name))
+        return result
+
+    def _get_function_signature(self, pyfunction, add_module=False):
+        location = self._location(pyfunction, add_module)
+        if isinstance(pyfunction, pyobjects.PyFunction):
+            info = functionutils.DefinitionInfo.read(pyfunction)
+            return location + info.to_string()
+        else:
+            return '%s(%s)' % (location + pyfunction.get_name(),
+                               ', '.join(pyfunction.get_param_names()))
+
+    def _location(self, pyobject, add_module=False):
+        location = []
+        parent = pyobject.parent
+        while parent and not isinstance(parent, pyobjects.AbstractModule):
+            location.append(parent.get_name())
+            location.append('.')
+            parent = parent.parent
+        if add_module:
+            if isinstance(pyobject, pyobjects.PyFunction):
+                module = pyobject.get_module()
+                location.insert(0, self._get_module(pyobject))
+            if isinstance(parent, builtins.BuiltinModule):
+                location.insert(0, parent.get_name() + '.')
+        return ''.join(location)
+
+    def _get_module(self, pyfunction):
+        module = pyfunction.get_module()
+        if module is not None:
+            resource = module.get_resource()
+            if resource is not None:
+                return pyfunction.pycore.modname(resource) + '.'
+        return ''
+
+    def _trim_docstring(self, docstring, indents=0):
+        """The sample code from :PEP:`257`"""
+        if not docstring:
+            return ''
+        # Convert tabs to spaces (following normal Python rules)
+        # and split into a list of lines:
+        lines = docstring.expandtabs().splitlines()
+        # Determine minimum indentation (first line doesn't count):
+        indent = sys.maxint
+        for line in lines[1:]:
+            stripped = line.lstrip()
+            if stripped:
+                indent = min(indent, len(line) - len(stripped))
+        # Remove indentation (first line is special):
+        trimmed = [lines[0].strip()]
+        if indent < sys.maxint:
+            for line in lines[1:]:
+                trimmed.append(line[indent:].rstrip())
+        # Strip off trailing and leading blank lines:
+        while trimmed and not trimmed[-1]:
+            trimmed.pop()
+        while trimmed and not trimmed[0]:
+            trimmed.pop(0)
+        # Return a single string:
+        return '\n'.join((' ' * indents + line for line in trimmed))
+
+
+# Deprecated classes
+
+class TemplateProposal(CodeAssistProposal):
+    def __init__(self, name, template):
+        warnings.warn('TemplateProposal is deprecated.',
+                      DeprecationWarning, stacklevel=2)
+        super(TemplateProposal, self).__init__(name, 'template')
+        self.template = template
+
+
+class Template(object):
+
+    def __init__(self, template):
+        self.template = template
+        warnings.warn('Template is deprecated.',
+                      DeprecationWarning, stacklevel=2)
+
+    def variables(self):
+        return []
+
+    def substitute(self, mapping):
+        return self.template
+
+    def get_cursor_location(self, mapping):
+        return len(self.template)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/contrib/finderrors.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,91 @@
+"""Finding bad name and attribute accesses
+
+`find_errors` function can be used to find possible bad name and
+attribute accesses.  As an example::
+
+  errors = find_errors(project, project.get_resource('mod.py'))
+  for error in errors:
+      print '%s: %s' % (error.lineno, error.error)
+
+prints possible errors for ``mod.py`` file.
+
+TODO:
+
+* use task handles
+* reporting names at most once
+* attributes of extension modules that don't appear in
+  extension_modules project config can be ignored
+* not calling `PyScope.get_inner_scope_for_line()` if it is a
+  bottleneck; needs profiling
+* not reporting occurrences where rope cannot infer the object
+* rope saves multiple objects for some of the names in its objectdb
+  use all of them not to give false positives
+* ... ;-)
+
+"""
+from rope.base import ast, evaluate, pyobjects
+
+
+def find_errors(project, resource):
+    """Find possible bad name and attribute accesses
+
+    It returns a list of `Error`\s.
+    """
+    pymodule = project.pycore.resource_to_pyobject(resource)
+    finder = _BadAccessFinder(pymodule)
+    ast.walk(pymodule.get_ast(), finder)
+    return finder.errors
+
+
+class _BadAccessFinder(object):
+
+    def __init__(self, pymodule):
+        self.pymodule = pymodule
+        self.scope = pymodule.get_scope()
+        self.errors = []
+
+    def _Name(self, node):
+        if isinstance(node.ctx, (ast.Store, ast.Param)):
+            return
+        scope = self.scope.get_inner_scope_for_line(node.lineno)
+        pyname = scope.lookup(node.id)
+        if pyname is None:
+            self._add_error(node, 'Unresolved variable')
+        elif self._is_defined_after(scope, pyname, node.lineno):
+            self._add_error(node, 'Defined later')
+
+    def _Attribute(self, node):
+        if not isinstance(node.ctx, ast.Store):
+            scope = self.scope.get_inner_scope_for_line(node.lineno)
+            pyname = evaluate.eval_node(scope, node.value)
+            if pyname is not None and \
+               pyname.get_object() != pyobjects.get_unknown():
+                if node.attr not in pyname.get_object():
+                    self._add_error(node, 'Unresolved attribute')
+        ast.walk(node.value, self)
+
+    def _add_error(self, node, msg):
+        if isinstance(node, ast.Attribute):
+            name = node.attr
+        else:
+            name = node.id
+        if name != 'None':
+            error = Error(node.lineno, msg + ' ' + name)
+            self.errors.append(error)
+
+    def _is_defined_after(self, scope, pyname, lineno):
+        location = pyname.get_definition_location()
+        if location is not None and location[1] is not None:
+            if location[0] == self.pymodule and \
+               lineno <= location[1] <= scope.get_end():
+                return True
+
+
+class Error(object):
+
+    def __init__(self, lineno, error):
+        self.lineno = lineno
+        self.error = error
+
+    def __str__(self):
+        return '%s: %s' % (self.lineno, self.error)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/contrib/findit.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,110 @@
+import rope.base.codeanalyze
+import rope.base.evaluate
+import rope.base.pyobjects
+from rope.base import taskhandle, exceptions, worder
+from rope.contrib import fixsyntax
+from rope.refactor import occurrences
+
+
+def find_occurrences(project, resource, offset, unsure=False, resources=None,
+                     in_hierarchy=False, task_handle=taskhandle.NullTaskHandle()):
+    """Return a list of `Location`\s
+
+    If `unsure` is `True`, possible matches are returned, too.  You
+    can use `Location.unsure` to see which are unsure occurrences.
+    `resources` can be a list of `rope.base.resource.File`\s that
+    should be searched for occurrences; if `None` all python files
+    in the project are searched.
+
+    """
+    name = worder.get_name_at(resource, offset)
+    this_pymodule = project.pycore.resource_to_pyobject(resource)
+    primary, pyname = rope.base.evaluate.eval_location2(
+        this_pymodule, offset)
+    def is_match(occurrence):
+        return unsure
+    finder = occurrences.create_finder(
+        project.pycore, name, pyname, unsure=is_match,
+        in_hierarchy=in_hierarchy, instance=primary)
+    if resources is None:
+        resources = project.pycore.get_python_files()
+    job_set = task_handle.create_jobset('Finding Occurrences',
+                                        count=len(resources))
+    return _find_locations(finder, resources, job_set)
+
+
+def find_implementations(project, resource, offset, resources=None,
+                         task_handle=taskhandle.NullTaskHandle()):
+    """Find the places a given method is overridden.
+
+    Finds the places a method is implemented.  Returns a list of
+    `Location`\s.
+    """
+    name = worder.get_name_at(resource, offset)
+    this_pymodule = project.pycore.resource_to_pyobject(resource)
+    pyname = rope.base.evaluate.eval_location(this_pymodule, offset)
+    if pyname is not None:
+        pyobject = pyname.get_object()
+        if not isinstance(pyobject, rope.base.pyobjects.PyFunction) or \
+           pyobject.get_kind() != 'method':
+            raise exceptions.BadIdentifierError('Not a method!')
+    else:
+        raise exceptions.BadIdentifierError('Cannot resolve the identifier!')
+    def is_defined(occurrence):
+        if not occurrence.is_defined():
+            return False
+    def not_self(occurrence):
+        if occurrence.get_pyname().get_object() == pyname.get_object():
+            return False
+    filters = [is_defined, not_self,
+               occurrences.InHierarchyFilter(pyname, True)]
+    finder = occurrences.Finder(project.pycore, name, filters=filters)
+    if resources is None:
+        resources = project.pycore.get_python_files()
+    job_set = task_handle.create_jobset('Finding Implementations',
+                                        count=len(resources))
+    return _find_locations(finder, resources, job_set)
+
+
+def find_definition(project, code, offset, resource=None, maxfixes=1):
+    """Return the definition location of the python name at `offset`
+
+    A `Location` object is returned if the definition location can be
+    determined, otherwise ``None`` is returned.
+    """
+    fixer = fixsyntax.FixSyntax(project.pycore, code, resource, maxfixes)
+    main_module = fixer.get_pymodule()
+    pyname = fixer.pyname_at(offset)
+    if pyname is not None:
+        module, lineno = pyname.get_definition_location()
+        name = rope.base.worder.Worder(code).get_word_at(offset)
+        if lineno is not None:
+            start = module.lines.get_line_start(lineno)
+            def check_offset(occurrence):
+                if occurrence.offset < start:
+                    return False
+            pyname_filter = occurrences.PyNameFilter(pyname)
+            finder = occurrences.Finder(project.pycore, name,
+                                        [check_offset, pyname_filter])
+            for occurrence in finder.find_occurrences(pymodule=module):
+                return Location(occurrence)
+
+
+class Location(object):
+
+    def __init__(self, occurrence):
+        self.resource = occurrence.resource
+        self.region = occurrence.get_word_range()
+        self.offset = self.region[0]
+        self.unsure = occurrence.is_unsure()
+        self.lineno = occurrence.lineno
+
+
+def _find_locations(finder, resources, job_set):
+    result = []
+    for resource in resources:
+        job_set.started_job(resource.path)
+        for occurrence in finder.find_occurrences(resource):
+            result.append(Location(occurrence))
+        job_set.finished_job()
+    return result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/contrib/fixmodnames.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,69 @@
+"""Fix the name of modules
+
+This module is useful when you want to rename many of the modules in
+your project.  That can happen specially when you want to change their
+naming style.
+
+For instance::
+
+  fixer = FixModuleNames(project)
+  changes = fixer.get_changes(fixer=str.lower)
+  project.do(changes)
+
+Here it renames all modules and packages to use lower-cased chars.
+You can tell it to use any other style by using the ``fixer``
+argument.
+
+"""
+from rope.base import change, taskhandle
+from rope.contrib import changestack
+from rope.refactor import rename
+
+
+class FixModuleNames(object):
+
+    def __init__(self, project):
+        self.project = project
+
+    def get_changes(self, fixer=str.lower,
+                    task_handle=taskhandle.NullTaskHandle()):
+        """Fix module names
+
+        `fixer` is a function that takes and returns a `str`.  Given
+        the name of a module, it should return the fixed name.
+
+        """
+        stack = changestack.ChangeStack(self.project, 'Fixing module names')
+        jobset = task_handle.create_jobset('Fixing module names',
+                                           self._count_fixes(fixer) + 1)
+        try:
+            while True:
+                for resource in self._tobe_fixed(fixer):
+                    jobset.started_job(resource.path)
+                    renamer = rename.Rename(self.project, resource)
+                    changes = renamer.get_changes(fixer(self._name(resource)))
+                    stack.push(changes)
+                    jobset.finished_job()
+                    break
+                else:
+                    break
+        finally:
+            jobset.started_job('Reverting to original state')
+            stack.pop_all()
+            jobset.finished_job()
+        return stack.merged()
+
+    def _count_fixes(self, fixer):
+        return len(list(self._tobe_fixed(fixer)))
+
+    def _tobe_fixed(self, fixer):
+        for resource in self.project.pycore.get_python_files():
+            modname = self._name(resource)
+            if modname != fixer(modname):
+                yield resource
+
+    def _name(self, resource):
+        modname = resource.name.rsplit('.', 1)[0]
+        if modname == '__init__':
+            modname = resource.parent.name
+        return modname
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/contrib/fixsyntax.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,178 @@
+import rope.base.codeanalyze
+import rope.base.evaluate
+from rope.base import worder, exceptions, utils
+from rope.base.codeanalyze import ArrayLinesAdapter, LogicalLineFinder
+
+
+class FixSyntax(object):
+
+    def __init__(self, pycore, code, resource, maxfixes=1):
+        self.pycore = pycore
+        self.code = code
+        self.resource = resource
+        self.maxfixes = maxfixes
+
+    @utils.saveit
+    def get_pymodule(self):
+        """Get a `PyModule`"""
+        errors = []
+        code = self.code
+        tries = 0
+        while True:
+            try:
+                if tries == 0 and self.resource is not None and \
+                   self.resource.read() == code:
+                    return self.pycore.resource_to_pyobject(self.resource,
+                                                            force_errors=True)
+                return self.pycore.get_string_module(
+                    code, resource=self.resource, force_errors=True)
+            except exceptions.ModuleSyntaxError, e:
+                if tries < self.maxfixes:
+                    tries += 1
+                    self.commenter.comment(e.lineno)
+                    code = '\n'.join(self.commenter.lines)
+                    errors.append('  * line %s: %s ... fixed' % (e.lineno,
+                                                                 e.message_))
+                else:
+                    errors.append('  * line %s: %s ... raised!' % (e.lineno,
+                                                                   e.message_))
+                    new_message = ('\nSyntax errors in file %s:\n' % e.filename) \
+                                   + '\n'.join(errors)
+                    raise exceptions.ModuleSyntaxError(e.filename, e.lineno,
+                                                       new_message)
+
+    @property
+    @utils.saveit
+    def commenter(self):
+        return _Commenter(self.code)
+
+    def pyname_at(self, offset):
+        pymodule = self.get_pymodule()
+        def old_pyname():
+            word_finder = worder.Worder(self.code, True)
+            expression = word_finder.get_primary_at(offset)
+            expression = expression.replace('\\\n', ' ').replace('\n', ' ')
+            lineno = self.code.count('\n', 0, offset)
+            scope = pymodule.get_scope().get_inner_scope_for_line(lineno)
+            return rope.base.evaluate.eval_str(scope, expression)
+        new_code = pymodule.source_code
+        def new_pyname():
+            newoffset = self.commenter.transfered_offset(offset)
+            return rope.base.evaluate.eval_location(pymodule, newoffset)
+        if new_code.startswith(self.code[:offset + 1]):
+            return new_pyname()
+        result = old_pyname()
+        if result is None:
+            return new_pyname()
+        return result
+
+
+class _Commenter(object):
+
+    def __init__(self, code):
+        self.code = code
+        self.lines = self.code.split('\n')
+        self.lines.append('\n')
+        self.origs = range(len(self.lines) + 1)
+        self.diffs = [0] * (len(self.lines) + 1)
+
+    def comment(self, lineno):
+        start = _logical_start(self.lines, lineno, check_prev=True) - 1
+        # using self._get_stmt_end() instead of self._get_block_end()
+        # to lower commented lines
+        end = self._get_stmt_end(start)
+        indents = _get_line_indents(self.lines[start])
+        if 0 < start:
+            last_lineno = self._last_non_blank(start - 1)
+            last_line = self.lines[last_lineno]
+            if last_line.rstrip().endswith(':'):
+                indents = _get_line_indents(last_line) + 4
+        self._set(start, ' ' * indents + 'pass')
+        for line in range(start + 1, end + 1):
+            self._set(line, self.lines[start])
+        self._fix_incomplete_try_blocks(lineno, indents)
+
+    def transfered_offset(self, offset):
+        lineno = self.code.count('\n', 0, offset)
+        diff = sum(self.diffs[:lineno])
+        return offset + diff
+
+    def _last_non_blank(self, start):
+        while start > 0 and self.lines[start].strip() == '':
+            start -= 1
+        return start
+
+    def _get_block_end(self, lineno):
+        end_line = lineno
+        base_indents = _get_line_indents(self.lines[lineno])
+        for i in range(lineno + 1, len(self.lines)):
+            if _get_line_indents(self.lines[i]) >= base_indents:
+                end_line = i
+            else:
+                break
+        return end_line
+
+    def _get_stmt_end(self, lineno):
+        end_line = lineno
+        base_indents = _get_line_indents(self.lines[lineno])
+        for i in range(lineno + 1, len(self.lines)):
+            if _get_line_indents(self.lines[i]) <= base_indents:
+                return i - 1
+        return lineno
+
+    def _fix_incomplete_try_blocks(self, lineno, indents):
+        block_start = lineno
+        last_indents = current_indents = indents
+        while block_start > 0:
+            block_start = rope.base.codeanalyze.get_block_start(
+                ArrayLinesAdapter(self.lines), block_start) - 1
+            if self.lines[block_start].strip().startswith('try:'):
+                indents = _get_line_indents(self.lines[block_start])
+                if indents > last_indents:
+                    continue
+                last_indents = indents
+                block_end = self._find_matching_deindent(block_start)
+                line = self.lines[block_end].strip()
+                if not (line.startswith('finally:') or
+                        line.startswith('except ') or
+                        line.startswith('except:')):
+                    self._insert(block_end, ' ' * indents + 'finally:')
+                    self._insert(block_end + 1, ' ' * indents + '    pass')
+
+    def _find_matching_deindent(self, line_number):
+        indents = _get_line_indents(self.lines[line_number])
+        current_line = line_number + 1
+        while current_line < len(self.lines):
+            line = self.lines[current_line]
+            if not line.strip().startswith('#') and not line.strip() == '':
+                # HACK: We should have used logical lines here
+                if _get_line_indents(self.lines[current_line]) <= indents:
+                    return current_line
+            current_line += 1
+        return len(self.lines) - 1
+
+    def _set(self, lineno, line):
+        self.diffs[self.origs[lineno]] += len(line) - len(self.lines[lineno])
+        self.lines[lineno] = line
+
+    def _insert(self, lineno, line):
+        self.diffs[self.origs[lineno]] += len(line) + 1
+        self.origs.insert(lineno, self.origs[lineno])
+        self.lines.insert(lineno, line)
+
+def _logical_start(lines, lineno, check_prev=False):
+    logical_finder = LogicalLineFinder(ArrayLinesAdapter(lines))
+    if check_prev:
+        prev = lineno - 1
+        while prev > 0:
+            start, end = logical_finder.logical_line_in(prev)
+            if end is None or start <= lineno < end:
+                return start
+            if start <= prev:
+                break
+            prev -= 1
+    return logical_finder.logical_line_in(lineno)[0]
+
+
+def _get_line_indents(line):
+    return rope.base.codeanalyze.count_line_indents(line)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/contrib/generate.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,355 @@
+import rope.base.evaluate
+from rope.base import change, pyobjects, exceptions, pynames, worder, codeanalyze
+from rope.refactor import sourceutils, importutils, functionutils, suites
+
+
+def create_generate(kind, project, resource, offset):
+    """A factory for creating `Generate` objects
+
+    `kind` can be 'variable', 'function', 'class', 'module' or
+    'package'.
+
+    """
+    generate = eval('Generate' + kind.title())
+    return generate(project, resource, offset)
+
+
+def create_module(project, name, sourcefolder=None):
+    """Creates a module and returns a `rope.base.resources.File`"""
+    if sourcefolder is None:
+        sourcefolder = project.root
+    packages = name.split('.')
+    parent = sourcefolder
+    for package in packages[:-1]:
+        parent = parent.get_child(package)
+    return parent.create_file(packages[-1] + '.py')
+
+def create_package(project, name, sourcefolder=None):
+    """Creates a package and returns a `rope.base.resources.Folder`"""
+    if sourcefolder is None:
+        sourcefolder = project.root
+    packages = name.split('.')
+    parent = sourcefolder
+    for package in packages[:-1]:
+        parent = parent.get_child(package)
+    made_packages = parent.create_folder(packages[-1])
+    made_packages.create_file('__init__.py')
+    return made_packages
+
+
+class _Generate(object):
+
+    def __init__(self, project, resource, offset):
+        self.project = project
+        self.resource = resource
+        self.info = self._generate_info(project, resource, offset)
+        self.name = self.info.get_name()
+        self._check_exceptional_conditions()
+
+    def _generate_info(self, project, resource, offset):
+        return _GenerationInfo(project.pycore, resource, offset)
+
+    def _check_exceptional_conditions(self):
+        if self.info.element_already_exists():
+            raise exceptions.RefactoringError(
+                'Element <%s> already exists.' % self.name)
+        if not self.info.primary_is_found():
+            raise exceptions.RefactoringError(
+                'Cannot determine the scope <%s> should be defined in.' % self.name)
+
+    def get_changes(self):
+        changes = change.ChangeSet('Generate %s <%s>' %
+                                   (self._get_element_kind(), self.name))
+        indents = self.info.get_scope_indents()
+        blanks = self.info.get_blank_lines()
+        base_definition = sourceutils.fix_indentation(self._get_element(), indents)
+        definition = '\n' * blanks[0] + base_definition + '\n' * blanks[1]
+
+        resource = self.info.get_insertion_resource()
+        start, end = self.info.get_insertion_offsets()
+
+        collector = codeanalyze.ChangeCollector(resource.read())
+        collector.add_change(start, end, definition)
+        changes.add_change(change.ChangeContents(
+                           resource, collector.get_changed()))
+        return changes
+
+    def get_location(self):
+        return (self.info.get_insertion_resource(),
+                self.info.get_insertion_lineno())
+
+    def _get_element_kind(self):
+        raise NotImplementedError()
+
+    def _get_element(self):
+        raise NotImplementedError()
+
+
+class GenerateFunction(_Generate):
+
+    def _generate_info(self, project, resource, offset):
+        return _FunctionGenerationInfo(project.pycore, resource, offset)
+
+    def _get_element(self):
+        decorator = ''
+        args = []
+        if self.info.is_static_method():
+            decorator = '@staticmethod\n'
+        if self.info.is_method() or self.info.is_constructor() or \
+           self.info.is_instance():
+            args.append('self')
+        args.extend(self.info.get_passed_args())
+        definition = '%sdef %s(%s):\n    pass\n' % (decorator, self.name,
+                                                    ', '.join(args))
+        return definition
+
+    def _get_element_kind(self):
+        return 'Function'
+
+
+class GenerateVariable(_Generate):
+
+    def _get_element(self):
+        return '%s = None\n' % self.name
+
+    def _get_element_kind(self):
+        return 'Variable'
+
+
+class GenerateClass(_Generate):
+
+    def _get_element(self):
+        return 'class %s(object):\n    pass\n' % self.name
+
+    def _get_element_kind(self):
+        return 'Class'
+
+
+class GenerateModule(_Generate):
+
+    def get_changes(self):
+        package = self.info.get_package()
+        changes = change.ChangeSet('Generate Module <%s>' % self.name)
+        new_resource = self.project.get_file('%s/%s.py' % (package.path, self.name))
+        if new_resource.exists():
+            raise exceptions.RefactoringError(
+                'Module <%s> already exists' % new_resource.path)
+        changes.add_change(change.CreateResource(new_resource))
+        changes.add_change(_add_import_to_module(
+                           self.project.pycore, self.resource, new_resource))
+        return changes
+
+    def get_location(self):
+        package = self.info.get_package()
+        return (package.get_child('%s.py' % self.name) , 1)
+
+
+class GeneratePackage(_Generate):
+
+    def get_changes(self):
+        package = self.info.get_package()
+        changes = change.ChangeSet('Generate Package <%s>' % self.name)
+        new_resource = self.project.get_folder('%s/%s' % (package.path, self.name))
+        if new_resource.exists():
+            raise exceptions.RefactoringError(
+                'Package <%s> already exists' % new_resource.path)
+        changes.add_change(change.CreateResource(new_resource))
+        changes.add_change(_add_import_to_module(
+                           self.project.pycore, self.resource, new_resource))
+        child = self.project.get_folder(package.path + '/' + self.name)
+        changes.add_change(change.CreateFile(child, '__init__.py'))
+        return changes
+
+    def get_location(self):
+        package = self.info.get_package()
+        child = package.get_child(self.name)
+        return (child.get_child('__init__.py') , 1)
+
+
+def _add_import_to_module(pycore, resource, imported):
+    pymodule = pycore.resource_to_pyobject(resource)
+    import_tools = importutils.ImportTools(pycore)
+    module_imports = import_tools.module_imports(pymodule)
+    module_name = pycore.modname(imported)
+    new_import = importutils.NormalImport(((module_name, None), ))
+    module_imports.add_import(new_import)
+    return change.ChangeContents(resource, module_imports.get_changed_source())
+
+
+class _GenerationInfo(object):
+
+    def __init__(self, pycore, resource, offset):
+        self.pycore = pycore
+        self.resource = resource
+        self.offset = offset
+        self.source_pymodule = self.pycore.resource_to_pyobject(resource)
+        finder = rope.base.evaluate.ScopeNameFinder(self.source_pymodule)
+        self.primary, self.pyname = finder.get_primary_and_pyname_at(offset)
+        self._init_fields()
+
+    def _init_fields(self):
+        self.source_scope = self._get_source_scope()
+        self.goal_scope = self._get_goal_scope()
+        self.goal_pymodule = self._get_goal_module(self.goal_scope)
+
+    def _get_goal_scope(self):
+        if self.primary is None:
+            return self._get_source_scope()
+        pyobject = self.primary.get_object()
+        if isinstance(pyobject, pyobjects.PyDefinedObject):
+            return pyobject.get_scope()
+        elif isinstance(pyobject.get_type(), pyobjects.PyClass):
+            return pyobject.get_type().get_scope()
+
+    def _get_goal_module(self, scope):
+        if scope is None:
+            return
+        while scope.parent is not None:
+            scope = scope.parent
+        return scope.pyobject
+
+    def _get_source_scope(self):
+        module_scope = self.source_pymodule.get_scope()
+        lineno = self.source_pymodule.lines.get_line_number(self.offset)
+        return module_scope.get_inner_scope_for_line(lineno)
+
+    def get_insertion_lineno(self):
+        lines = self.goal_pymodule.lines
+        if self.goal_scope == self.source_scope:
+            line_finder = self.goal_pymodule.logical_lines
+            lineno = lines.get_line_number(self.offset)
+            lineno = line_finder.logical_line_in(lineno)[0]
+            root = suites.ast_suite_tree(self.goal_scope.pyobject.get_ast())
+            suite = root.find_suite(lineno)
+            indents = sourceutils.get_indents(lines, lineno)
+            while self.get_scope_indents() < indents:
+                lineno = suite.get_start()
+                indents = sourceutils.get_indents(lines, lineno)
+                suite = suite.parent
+            return lineno
+        else:
+            return min(self.goal_scope.get_end() + 1, lines.length())
+
+    def get_insertion_resource(self):
+        return self.goal_pymodule.get_resource()
+
+    def get_insertion_offsets(self):
+        if self.goal_scope.get_kind() == 'Class':
+            start, end = sourceutils.get_body_region(self.goal_scope.pyobject)
+            if self.goal_pymodule.source_code[start:end].strip() == 'pass':
+                return start, end
+        lines = self.goal_pymodule.lines
+        start = lines.get_line_start(self.get_insertion_lineno())
+        return (start, start)
+
+    def get_scope_indents(self):
+        if self.goal_scope.get_kind() == 'Module':
+            return 0
+        return sourceutils.get_indents(self.goal_pymodule.lines,
+                                       self.goal_scope.get_start()) + 4
+
+    def get_blank_lines(self):
+        if self.goal_scope.get_kind() == 'Module':
+            base_blanks = 2
+            if self.goal_pymodule.source_code.strip() == '':
+                base_blanks = 0
+        if self.goal_scope.get_kind() == 'Class':
+            base_blanks = 1
+        if self.goal_scope.get_kind() == 'Function':
+            base_blanks = 0
+        if self.goal_scope == self.source_scope:
+            return (0, base_blanks)
+        return (base_blanks, 0)
+
+    def get_package(self):
+        primary = self.primary
+        if self.primary is None:
+            return self.pycore.get_source_folders()[0]
+        if isinstance(primary.get_object(), pyobjects.PyPackage):
+            return primary.get_object().get_resource()
+        raise exceptions.RefactoringError(
+            'A module/package can be only created in a package.')
+
+    def primary_is_found(self):
+        return self.goal_scope is not None
+
+    def element_already_exists(self):
+        if self.pyname is None or isinstance(self.pyname, pynames.UnboundName):
+            return False
+        return self.get_name() in self.goal_scope.get_defined_names()
+
+    def get_name(self):
+        return worder.get_name_at(self.resource, self.offset)
+
+
+class _FunctionGenerationInfo(_GenerationInfo):
+
+    def _get_goal_scope(self):
+        if self.is_constructor():
+            return self.pyname.get_object().get_scope()
+        if self.is_instance():
+            return self.pyname.get_object().get_type().get_scope()
+        if self.primary is None:
+            return self._get_source_scope()
+        pyobject = self.primary.get_object()
+        if isinstance(pyobject, pyobjects.PyDefinedObject):
+            return pyobject.get_scope()
+        elif isinstance(pyobject.get_type(), pyobjects.PyClass):
+            return pyobject.get_type().get_scope()
+
+    def element_already_exists(self):
+        if self.pyname is None or isinstance(self.pyname, pynames.UnboundName):
+            return False
+        return self.get_name() in self.goal_scope.get_defined_names()
+
+    def is_static_method(self):
+        return self.primary is not None and \
+               isinstance(self.primary.get_object(), pyobjects.PyClass)
+
+    def is_method(self):
+        return self.primary is not None and \
+               isinstance(self.primary.get_object().get_type(), pyobjects.PyClass)
+
+    def is_constructor(self):
+        return self.pyname is not None and \
+               isinstance(self.pyname.get_object(), pyobjects.PyClass)
+
+    def is_instance(self):
+        if self.pyname is None:
+            return False
+        pyobject = self.pyname.get_object()
+        return isinstance(pyobject.get_type(), pyobjects.PyClass)
+
+    def get_name(self):
+        if self.is_constructor():
+            return '__init__'
+        if self.is_instance():
+            return '__call__'
+        return worder.get_name_at(self.resource, self.offset)
+
+    def get_passed_args(self):
+        result = []
+        source = self.source_pymodule.source_code
+        finder = worder.Worder(source)
+        if finder.is_a_function_being_called(self.offset):
+            start, end = finder.get_primary_range(self.offset)
+            parens_start, parens_end = finder.get_word_parens_range(end - 1)
+            call = source[start:parens_end]
+            parser = functionutils._FunctionParser(call, False)
+            args, keywords = parser.get_parameters()
+            for arg in args:
+                if self._is_id(arg):
+                    result.append(arg)
+                else:
+                    result.append('arg%d' % len(result))
+            for name, value in keywords:
+                result.append(name)
+        return result
+
+    def _is_id(self, arg):
+        def id_or_underline(c):
+            return c.isalpha() or c == '_'
+        for c in arg:
+            if not id_or_underline(c) and not c.isdigit():
+                return False
+        return id_or_underline(arg[0])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/__init__.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,55 @@
+"""rope refactor package
+
+This package contains modules that perform python refactorings.
+Refactoring classes perform refactorings in 4 steps:
+
+1. Collect some data for performing the refactoring and use them
+   to construct a refactoring class.  Like::
+
+     renamer = Rename(project, resource, offset)
+
+2. Some refactorings give you useful information about the
+   refactoring after their construction.  Like::
+
+     print(renamer.get_old_name())
+
+3. Give the refactoring class more information about how to
+   perform the refactoring and get the changes this refactoring is
+   going to make.  This is done by calling `get_changes` method of the
+   refactoring class.  Like::
+
+     changes = renamer.get_changes(new_name)
+
+4. You can commit the changes.  Like::
+
+     project.do(changes)
+
+These steps are like the steps IDEs usually do for performing a
+refactoring.  These are the things an IDE does in each step:
+
+1. Construct a refactoring object by giving it information like
+   resource, offset and ... .  Some of the refactoring problems (like
+   performing rename refactoring on language keywords) can be reported
+   here.
+2. Print some information about the refactoring and ask the user
+   about the information that are necessary for completing the
+   refactoring (like new name).
+3. Call the `get_changes` by passing it information asked from
+   the user (if necessary) and get and preview the changes returned by
+   it.
+4. perform the refactoring.
+
+From ``0.5m5`` release the `get_changes()` method of some time-
+consuming refactorings take an optional `rope.base.taskhandle.
+TaskHandle` parameter.  You can use this object for stopping or
+monitoring the progress of refactorings.
+
+"""
+from rope.refactor.importutils import ImportOrganizer
+from rope.refactor.topackage import ModuleToPackage
+
+
+__all__ = ['rename', 'move', 'inline', 'extract', 'restructure', 'topackage',
+           'importutils', 'usefunction', 'change_signature',
+           'encapsulate_field', 'introduce_factory', 'introduce_parameter',
+           'localtofield', 'method_object', 'multiproject']
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/change_signature.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,342 @@
+import copy
+
+import rope.base.exceptions
+from rope.base import pyobjects, taskhandle, evaluate, worder, codeanalyze, utils
+from rope.base.change import ChangeContents, ChangeSet
+from rope.refactor import occurrences, functionutils
+
+
+class ChangeSignature(object):
+
+    def __init__(self, project, resource, offset):
+        self.pycore = project.pycore
+        self.resource = resource
+        self.offset = offset
+        self._set_name_and_pyname()
+        if self.pyname is None or self.pyname.get_object() is None or \
+           not isinstance(self.pyname.get_object(), pyobjects.PyFunction):
+            raise rope.base.exceptions.RefactoringError(
+                'Change method signature should be performed on functions')
+
+    def _set_name_and_pyname(self):
+        self.name = worder.get_name_at(self.resource, self.offset)
+        this_pymodule = self.pycore.resource_to_pyobject(self.resource)
+        self.primary, self.pyname = evaluate.eval_location2(
+            this_pymodule, self.offset)
+        if self.pyname is None:
+            return
+        pyobject = self.pyname.get_object()
+        if isinstance(pyobject, pyobjects.PyClass) and \
+           '__init__' in pyobject:
+            self.pyname = pyobject['__init__']
+            self.name = '__init__'
+        pyobject = self.pyname.get_object()
+        self.others = None
+        if self.name == '__init__' and \
+           isinstance(pyobject, pyobjects.PyFunction) and \
+           isinstance(pyobject.parent, pyobjects.PyClass):
+            pyclass = pyobject.parent
+            self.others = (pyclass.get_name(),
+                           pyclass.parent[pyclass.get_name()])
+
+    def _change_calls(self, call_changer, in_hierarchy=None, resources=None,
+                      handle=taskhandle.NullTaskHandle()):
+        if resources is None:
+            resources = self.pycore.get_python_files()
+        changes = ChangeSet('Changing signature of <%s>' % self.name)
+        job_set = handle.create_jobset('Collecting Changes', len(resources))
+        finder = occurrences.create_finder(
+            self.pycore, self.name, self.pyname, instance=self.primary,
+            in_hierarchy=in_hierarchy and self.is_method())
+        if self.others:
+            name, pyname = self.others
+            constructor_finder = occurrences.create_finder(
+                self.pycore, name, pyname, only_calls=True)
+            finder = _MultipleFinders([finder, constructor_finder])
+        for file in resources:
+            job_set.started_job(file.path)
+            change_calls = _ChangeCallsInModule(
+                self.pycore, finder, file, call_changer)
+            changed_file = change_calls.get_changed_module()
+            if changed_file is not None:
+                changes.add_change(ChangeContents(file, changed_file))
+            job_set.finished_job()
+        return changes
+
+    def get_args(self):
+        """Get function arguments.
+
+        Return a list of ``(name, default)`` tuples for all but star
+        and double star arguments.  For arguments that don't have a
+        default, `None` will be used.
+        """
+        return self._definfo().args_with_defaults
+
+    def is_method(self):
+        pyfunction = self.pyname.get_object()
+        return isinstance(pyfunction.parent, pyobjects.PyClass)
+
+    @utils.deprecated('Use `ChangeSignature.get_args()` instead')
+    def get_definition_info(self):
+        return self._definfo()
+
+    def _definfo(self):
+        return functionutils.DefinitionInfo.read(self.pyname.get_object())
+
+    @utils.deprecated()
+    def normalize(self):
+        changer = _FunctionChangers(
+            self.pyname.get_object(), self.get_definition_info(),
+            [ArgumentNormalizer()])
+        return self._change_calls(changer)
+
+    @utils.deprecated()
+    def remove(self, index):
+        changer = _FunctionChangers(
+            self.pyname.get_object(), self.get_definition_info(),
+            [ArgumentRemover(index)])
+        return self._change_calls(changer)
+
+    @utils.deprecated()
+    def add(self, index, name, default=None, value=None):
+        changer = _FunctionChangers(
+            self.pyname.get_object(), self.get_definition_info(),
+            [ArgumentAdder(index, name, default, value)])
+        return self._change_calls(changer)
+
+    @utils.deprecated()
+    def inline_default(self, index):
+        changer = _FunctionChangers(
+            self.pyname.get_object(), self.get_definition_info(),
+            [ArgumentDefaultInliner(index)])
+        return self._change_calls(changer)
+
+    @utils.deprecated()
+    def reorder(self, new_ordering):
+        changer = _FunctionChangers(
+            self.pyname.get_object(), self.get_definition_info(),
+            [ArgumentReorderer(new_ordering)])
+        return self._change_calls(changer)
+
+    def get_changes(self, changers, in_hierarchy=False, resources=None,
+                    task_handle=taskhandle.NullTaskHandle()):
+        """Get changes caused by this refactoring
+
+        `changers` is a list of `_ArgumentChanger`\s.  If `in_hierarchy`
+        is `True` the changers are applyed to all matching methods in
+        the class hierarchy.
+        `resources` can be a list of `rope.base.resource.File`\s that
+        should be searched for occurrences; if `None` all python files
+        in the project are searched.
+
+        """
+        function_changer = _FunctionChangers(self.pyname.get_object(),
+                                             self._definfo(), changers)
+        return self._change_calls(function_changer, in_hierarchy,
+                                  resources, task_handle)
+
+
+class _FunctionChangers(object):
+
+    def __init__(self, pyfunction, definition_info, changers=None):
+        self.pyfunction = pyfunction
+        self.definition_info = definition_info
+        self.changers = changers
+        self.changed_definition_infos = self._get_changed_definition_infos()
+
+    def _get_changed_definition_infos(self):
+        result = []
+        definition_info = self.definition_info
+        result.append(definition_info)
+        for changer in self.changers:
+            definition_info = copy.deepcopy(definition_info)
+            changer.change_definition_info(definition_info)
+            result.append(definition_info)
+        return result
+
+    def change_definition(self, call):
+        return self.changed_definition_infos[-1].to_string()
+
+    def change_call(self, primary, pyname, call):
+        call_info = functionutils.CallInfo.read(
+            primary, pyname, self.definition_info, call)
+        mapping = functionutils.ArgumentMapping(self.definition_info, call_info)
+
+        for definition_info, changer in zip(self.changed_definition_infos, self.changers):
+            changer.change_argument_mapping(definition_info, mapping)
+
+        return mapping.to_call_info(self.changed_definition_infos[-1]).to_string()
+
+
+class _ArgumentChanger(object):
+
+    def change_definition_info(self, definition_info):
+        pass
+
+    def change_argument_mapping(self, definition_info, argument_mapping):
+        pass
+
+
+class ArgumentNormalizer(_ArgumentChanger):
+    pass
+
+
+class ArgumentRemover(_ArgumentChanger):
+
+    def __init__(self, index):
+        self.index = index
+
+    def change_definition_info(self, call_info):
+        if self.index < len(call_info.args_with_defaults):
+            del call_info.args_with_defaults[self.index]
+        elif self.index == len(call_info.args_with_defaults) and \
+           call_info.args_arg is not None:
+            call_info.args_arg = None
+        elif (self.index == len(call_info.args_with_defaults) and
+            call_info.args_arg is None and call_info.keywords_arg is not None) or \
+           (self.index == len(call_info.args_with_defaults) + 1 and
+            call_info.args_arg is not None and call_info.keywords_arg is not None):
+            call_info.keywords_arg = None
+
+    def change_argument_mapping(self, definition_info, mapping):
+        if self.index < len(definition_info.args_with_defaults):
+            name = definition_info.args_with_defaults[0]
+            if name in mapping.param_dict:
+                del mapping.param_dict[name]
+
+
+class ArgumentAdder(_ArgumentChanger):
+
+    def __init__(self, index, name, default=None, value=None):
+        self.index = index
+        self.name = name
+        self.default = default
+        self.value = value
+
+    def change_definition_info(self, definition_info):
+        for pair in definition_info.args_with_defaults:
+            if pair[0] == self.name:
+                raise rope.base.exceptions.RefactoringError(
+                    'Adding duplicate parameter: <%s>.' % self.name)
+        definition_info.args_with_defaults.insert(self.index,
+                                                  (self.name, self.default))
+
+    def change_argument_mapping(self, definition_info, mapping):
+        if self.value is not None:
+            mapping.param_dict[self.name] = self.value
+
+
+class ArgumentDefaultInliner(_ArgumentChanger):
+
+    def __init__(self, index):
+        self.index = index
+        self.remove = False
+
+    def change_definition_info(self, definition_info):
+        if self.remove:
+            definition_info.args_with_defaults[self.index] = \
+                (definition_info.args_with_defaults[self.index][0], None)
+
+    def change_argument_mapping(self, definition_info, mapping):
+        default = definition_info.args_with_defaults[self.index][1]
+        name = definition_info.args_with_defaults[self.index][0]
+        if default is not None and name not in mapping.param_dict:
+            mapping.param_dict[name] = default
+
+
+class ArgumentReorderer(_ArgumentChanger):
+
+    def __init__(self, new_order, autodef=None):
+        """Construct an `ArgumentReorderer`
+
+        Note that the `new_order` is a list containing the new
+        position of parameters; not the position each parameter
+        is going to be moved to. (changed in ``0.5m4``)
+
+        For example changing ``f(a, b, c)`` to ``f(c, a, b)``
+        requires passing ``[2, 0, 1]`` and *not* ``[1, 2, 0]``.
+
+        The `autodef` (automatic default) argument, forces rope to use
+        it as a default if a default is needed after the change.  That
+        happens when an argument without default is moved after
+        another that has a default value.  Note that `autodef` should
+        be a string or `None`; the latter disables adding automatic
+        default.
+
+        """
+        self.new_order = new_order
+        self.autodef = autodef
+
+    def change_definition_info(self, definition_info):
+        new_args = list(definition_info.args_with_defaults)
+        for new_index, index in enumerate(self.new_order):
+            new_args[new_index] = definition_info.args_with_defaults[index]
+        seen_default = False
+        for index, (arg, default) in enumerate(list(new_args)):
+            if default is not None:
+                seen_default = True
+            if seen_default and default is None and self.autodef is not None:
+                new_args[index] = (arg, self.autodef)
+        definition_info.args_with_defaults = new_args
+
+
+class _ChangeCallsInModule(object):
+
+    def __init__(self, pycore, occurrence_finder, resource, call_changer):
+        self.pycore = pycore
+        self.occurrence_finder = occurrence_finder
+        self.resource = resource
+        self.call_changer = call_changer
+
+    def get_changed_module(self):
+        word_finder = worder.Worder(self.source)
+        change_collector = codeanalyze.ChangeCollector(self.source)
+        for occurrence in self.occurrence_finder.find_occurrences(self.resource):
+            if not occurrence.is_called() and not occurrence.is_defined():
+                continue
+            start, end = occurrence.get_primary_range()
+            begin_parens, end_parens = word_finder.get_word_parens_range(end - 1)
+            if occurrence.is_called():
+                primary, pyname = occurrence.get_primary_and_pyname()
+                changed_call = self.call_changer.change_call(
+                    primary, pyname, self.source[start:end_parens])
+            else:
+                changed_call = self.call_changer.change_definition(
+                    self.source[start:end_parens])
+            if changed_call is not None:
+                change_collector.add_change(start, end_parens, changed_call)
+        return change_collector.get_changed()
+
+    @property
+    @utils.saveit
+    def pymodule(self):
+        return self.pycore.resource_to_pyobject(self.resource)
+
+    @property
+    @utils.saveit
+    def source(self):
+        if self.resource is not None:
+            return self.resource.read()
+        else:
+            return self.pymodule.source_code
+
+    @property
+    @utils.saveit
+    def lines(self):
+        return self.pymodule.lines
+
+
+class _MultipleFinders(object):
+
+    def __init__(self, finders):
+        self.finders = finders
+
+    def find_occurrences(self, resource=None, pymodule=None):
+        all_occurrences = []
+        for finder in self.finders:
+            all_occurrences.extend(finder.find_occurrences(resource, pymodule))
+        all_occurrences.sort(self._cmp_occurrences)
+        return all_occurrences
+
+    def _cmp_occurrences(self, o1, o2):
+        return cmp(o1.get_primary_range(), o2.get_primary_range())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/encapsulate_field.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,202 @@
+from rope.base import pynames, taskhandle, evaluate, exceptions, worder, utils
+from rope.base.change import ChangeSet, ChangeContents
+from rope.refactor import sourceutils, occurrences
+
+
+class EncapsulateField(object):
+
+    def __init__(self, project, resource, offset):
+        self.pycore = project.pycore
+        self.name = worder.get_name_at(resource, offset)
+        this_pymodule = self.pycore.resource_to_pyobject(resource)
+        self.pyname = evaluate.eval_location(this_pymodule, offset)
+        if not self._is_an_attribute(self.pyname):
+            raise exceptions.RefactoringError(
+                'Encapsulate field should be performed on class attributes.')
+        self.resource = self.pyname.get_definition_location()[0].get_resource()
+
+    def get_changes(self, getter=None, setter=None, resources=None,
+                    task_handle=taskhandle.NullTaskHandle()):
+        """Get the changes this refactoring makes
+
+        If `getter` is not `None`, that will be the name of the
+        getter, otherwise ``get_${field_name}`` will be used.  The
+        same is true for `setter` and if it is None set_${field_name} is
+        used.
+
+        `resources` can be a list of `rope.base.resource.File`\s that
+        the refactoring should be applied on; if `None` all python
+        files in the project are searched.
+
+        """
+        if resources is None:
+            resources = self.pycore.get_python_files()
+        changes = ChangeSet('Encapsulate field <%s>' % self.name)
+        job_set = task_handle.create_jobset('Collecting Changes',
+                                            len(resources))
+        if getter is None:
+            getter = 'get_' + self.name
+        if setter is None:
+            setter = 'set_' + self.name
+        renamer = GetterSetterRenameInModule(
+            self.pycore, self.name, self.pyname, getter, setter)
+        for file in resources:
+            job_set.started_job(file.path)
+            if file == self.resource:
+                result = self._change_holding_module(changes, renamer,
+                                                     getter, setter)
+                changes.add_change(ChangeContents(self.resource, result))
+            else:
+                result = renamer.get_changed_module(file)
+                if result is not None:
+                    changes.add_change(ChangeContents(file, result))
+            job_set.finished_job()
+        return changes
+
+    def get_field_name(self):
+        """Get the name of the field to be encapsulated"""
+        return self.name
+
+    def _is_an_attribute(self, pyname):
+        if pyname is not None and isinstance(pyname, pynames.AssignedName):
+            pymodule, lineno = self.pyname.get_definition_location()
+            scope = pymodule.get_scope().\
+                             get_inner_scope_for_line(lineno)
+            if scope.get_kind() == 'Class':
+                return pyname in scope.get_names().values()
+            parent = scope.parent
+            if parent is not None and parent.get_kind() == 'Class':
+                return pyname in parent.get_names().values()
+        return False
+
+    def _get_defining_class_scope(self):
+        defining_scope = self._get_defining_scope()
+        if defining_scope.get_kind() == 'Function':
+            defining_scope = defining_scope.parent
+        return defining_scope
+
+    def _get_defining_scope(self):
+        pymodule, line = self.pyname.get_definition_location()
+        return pymodule.get_scope().get_inner_scope_for_line(line)
+
+    def _change_holding_module(self, changes, renamer, getter, setter):
+        pymodule = self.pycore.resource_to_pyobject(self.resource)
+        class_scope = self._get_defining_class_scope()
+        defining_object = self._get_defining_scope().pyobject
+        start, end = sourceutils.get_body_region(defining_object)
+
+        new_source = renamer.get_changed_module(pymodule=pymodule,
+                                                skip_start=start, skip_end=end)
+        if new_source is not None:
+            pymodule = self.pycore.get_string_module(new_source, self.resource)
+            class_scope = pymodule.get_scope().\
+                          get_inner_scope_for_line(class_scope.get_start())
+        indents = sourceutils.get_indent(self.pycore) * ' '
+        getter = 'def %s(self):\n%sreturn self.%s' % \
+                 (getter, indents, self.name)
+        setter = 'def %s(self, value):\n%sself.%s = value' % \
+                 (setter, indents, self.name)
+        new_source = sourceutils.add_methods(pymodule, class_scope,
+                                             [getter, setter])
+        return new_source
+
+
+class GetterSetterRenameInModule(object):
+
+    def __init__(self, pycore, name, pyname, getter, setter):
+        self.pycore = pycore
+        self.name = name
+        self.finder = occurrences.create_finder(pycore, name, pyname)
+        self.getter = getter
+        self.setter = setter
+
+    def get_changed_module(self, resource=None, pymodule=None,
+                           skip_start=0, skip_end=0):
+        change_finder = _FindChangesForModule(self, resource, pymodule,
+                                              skip_start, skip_end)
+        return change_finder.get_changed_module()
+
+
+class _FindChangesForModule(object):
+
+    def __init__(self, finder, resource, pymodule, skip_start, skip_end):
+        self.pycore = finder.pycore
+        self.finder = finder.finder
+        self.getter = finder.getter
+        self.setter = finder.setter
+        self.resource = resource
+        self.pymodule = pymodule
+        self.last_modified = 0
+        self.last_set = None
+        self.set_index = None
+        self.skip_start = skip_start
+        self.skip_end = skip_end
+
+    def get_changed_module(self):
+        result = []
+        for occurrence in self.finder.find_occurrences(self.resource,
+                                                       self.pymodule):
+            start, end = occurrence.get_word_range()
+            if self.skip_start <= start < self.skip_end:
+                continue
+            self._manage_writes(start, result)
+            result.append(self.source[self.last_modified:start])
+            if self._is_assigned_in_a_tuple_assignment(occurrence):
+                raise exceptions.RefactoringError(
+                    'Cannot handle tuple assignments in encapsulate field.')
+            if occurrence.is_written():
+                assignment_type = self.worder.get_assignment_type(start)
+                if assignment_type == '=':
+                    result.append(self.setter + '(')
+                else:
+                    var_name = self.source[occurrence.get_primary_range()[0]:
+                                           start] + self.getter + '()'
+                    result.append(self.setter + '(' + var_name
+                                  + ' %s ' % assignment_type[:-1])
+                current_line = self.lines.get_line_number(start)
+                start_line, end_line = self.pymodule.logical_lines.\
+                                       logical_line_in(current_line)
+                self.last_set = self.lines.get_line_end(end_line)
+                end = self.source.index('=', end) + 1
+                self.set_index = len(result)
+            else:
+                result.append(self.getter + '()')
+            self.last_modified = end
+        if self.last_modified != 0:
+            self._manage_writes(len(self.source), result)
+            result.append(self.source[self.last_modified:])
+            return ''.join(result)
+        return None
+
+    def _manage_writes(self, offset, result):
+        if self.last_set is not None and self.last_set <= offset:
+            result.append(self.source[self.last_modified:self.last_set])
+            set_value = ''.join(result[self.set_index:]).strip()
+            del result[self.set_index:]
+            result.append(set_value + ')')
+            self.last_modified = self.last_set
+            self.last_set = None
+
+    def _is_assigned_in_a_tuple_assignment(self, occurance):
+        offset = occurance.get_word_range()[0]
+        return self.worder.is_assigned_in_a_tuple_assignment(offset)
+
+    @property
+    @utils.saveit
+    def source(self):
+        if self.resource is not None:
+            return self.resource.read()
+        else:
+            return self.pymodule.source_code
+
+    @property
+    @utils.saveit
+    def lines(self):
+        if self.pymodule is None:
+            self.pymodule = self.pycore.resource_to_pyobject(self.resource)
+        return self.pymodule.lines
+
+    @property
+    @utils.saveit
+    def worder(self):
+        return worder.Worder(self.source)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/extract.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,789 @@
+import re
+
+from rope.base import ast, codeanalyze
+from rope.base.change import ChangeSet, ChangeContents
+from rope.base.exceptions import RefactoringError
+from rope.refactor import (sourceutils, similarfinder,
+                           patchedast, suites, usefunction)
+
+
+# Extract refactoring has lots of special cases.  I tried to split it
+# to smaller parts to make it more manageable:
+#
+# _ExtractInfo: holds information about the refactoring; it is passed
+# to the parts that need to have information about the refactoring
+# 
+# _ExtractCollector: merely saves all of the information necessary for
+# performing the refactoring.
+#
+# _DefinitionLocationFinder: finds where to insert the definition.
+#
+# _ExceptionalConditionChecker: checks for exceptional conditions in
+# which the refactoring cannot be applied.
+#
+# _ExtractMethodParts: generates the pieces of code (like definition)
+# needed for performing extract method.
+#
+# _ExtractVariableParts: like _ExtractMethodParts for variables.
+#
+# _ExtractPerformer: Uses above classes to collect refactoring
+# changes.
+#
+# There are a few more helper functions and classes used by above
+# classes.
+class _ExtractRefactoring(object):
+
+    def __init__(self, project, resource, start_offset, end_offset,
+                 variable=False):
+        self.project = project
+        self.pycore = project.pycore
+        self.resource = resource
+        self.start_offset = self._fix_start(resource.read(), start_offset)
+        self.end_offset = self._fix_end(resource.read(), end_offset)
+
+    def _fix_start(self, source, offset):
+        while offset < len(source) and source[offset].isspace():
+            offset += 1
+        return offset
+
+    def _fix_end(self, source, offset):
+        while offset > 0 and source[offset - 1].isspace():
+            offset -= 1
+        return offset
+
+    def get_changes(self, extracted_name, similar=False, global_=False):
+        """Get the changes this refactoring makes
+
+        :parameters:
+            - `similar`: if `True`, similar expressions/statements are also
+              replaced.
+            - `global_`: if `True`, the extracted method/variable will
+              be global.
+
+        """
+        info = _ExtractInfo(
+            self.project, self.resource, self.start_offset, self.end_offset,
+            extracted_name, variable=self.kind == 'variable',
+            similar=similar, make_global=global_)
+        new_contents = _ExtractPerformer(info).extract()
+        changes = ChangeSet('Extract %s <%s>' % (self.kind,
+                                                 extracted_name))
+        changes.add_change(ChangeContents(self.resource, new_contents))
+        return changes
+
+
+class ExtractMethod(_ExtractRefactoring):
+
+    def __init__(self, *args, **kwds):
+        super(ExtractMethod, self).__init__(*args, **kwds)
+
+    kind = 'method'
+
+
+class ExtractVariable(_ExtractRefactoring):
+
+    def __init__(self, *args, **kwds):
+        kwds = dict(kwds)
+        kwds['variable'] = True
+        super(ExtractVariable, self).__init__(*args, **kwds)
+
+    kind = 'variable'
+
+
+class _ExtractInfo(object):
+    """Holds information about the extract to be performed"""
+
+    def __init__(self, project, resource, start, end, new_name,
+                 variable, similar, make_global):
+        self.pycore = project.pycore
+        self.resource = resource
+        self.pymodule = self.pycore.resource_to_pyobject(resource)
+        self.global_scope = self.pymodule.get_scope()
+        self.source = self.pymodule.source_code
+        self.lines = self.pymodule.lines
+        self.new_name = new_name
+        self.variable = variable
+        self.similar = similar
+        self._init_parts(start, end)
+        self._init_scope()
+        self.make_global = make_global
+
+    def _init_parts(self, start, end):
+        self.region = (self._choose_closest_line_end(start),
+                       self._choose_closest_line_end(end, end=True))
+
+        start = self.logical_lines.logical_line_in(
+            self.lines.get_line_number(self.region[0]))[0]
+        end = self.logical_lines.logical_line_in(
+            self.lines.get_line_number(self.region[1]))[1]
+        self.region_lines = (start, end)
+
+        self.lines_region = (self.lines.get_line_start(self.region_lines[0]),
+                             self.lines.get_line_end(self.region_lines[1]))
+
+    @property
+    def logical_lines(self):
+        return self.pymodule.logical_lines
+
+    def _init_scope(self):
+        start_line = self.region_lines[0]
+        scope = self.global_scope.get_inner_scope_for_line(start_line)
+        if scope.get_kind() != 'Module' and scope.get_start() == start_line:
+            scope = scope.parent
+        self.scope = scope
+        self.scope_region = self._get_scope_region(self.scope)
+
+    def _get_scope_region(self, scope):
+        return (self.lines.get_line_start(scope.get_start()),
+                self.lines.get_line_end(scope.get_end()) + 1)
+
+    def _choose_closest_line_end(self, offset, end=False):
+        lineno = self.lines.get_line_number(offset)
+        line_start = self.lines.get_line_start(lineno)
+        line_end = self.lines.get_line_end(lineno)
+        if self.source[line_start:offset].strip() == '':
+            if end:
+                return line_start - 1
+            else:
+                return line_start
+        elif self.source[offset:line_end].strip() == '':
+            return min(line_end, len(self.source))
+        return offset
+
+    @property
+    def one_line(self):
+        return self.region != self.lines_region and \
+               (self.logical_lines.logical_line_in(self.region_lines[0]) ==
+                self.logical_lines.logical_line_in(self.region_lines[1]))
+
+    @property
+    def global_(self):
+        return self.scope.parent is None
+
+    @property
+    def method(self):
+        return self.scope.parent is not None and \
+               self.scope.parent.get_kind() == 'Class'
+
+    @property
+    def indents(self):
+        return sourceutils.get_indents(self.pymodule.lines,
+                                       self.region_lines[0])
+
+    @property
+    def scope_indents(self):
+        if self.global_:
+            return 0
+        return sourceutils.get_indents(self.pymodule.lines,
+                                       self.scope.get_start())
+
+    @property
+    def extracted(self):
+        return self.source[self.region[0]:self.region[1]]
+
+    _returned = None
+    @property
+    def returned(self):
+        """Does the extracted piece contain return statement"""
+        if self._returned is None:
+            node = _parse_text(self.extracted)
+            self._returned = usefunction._returns_last(node)
+        return self._returned
+
+
+class _ExtractCollector(object):
+    """Collects information needed for performing the extract"""
+
+    def __init__(self, info):
+        self.definition = None
+        self.body_pattern = None
+        self.checks = {}
+        self.replacement_pattern = None
+        self.matches = None
+        self.replacements = None
+        self.definition_location = None
+
+
+class _ExtractPerformer(object):
+
+    def __init__(self, info):
+        self.info = info
+        _ExceptionalConditionChecker()(self.info)
+
+    def extract(self):
+        extract_info = self._collect_info()
+        content = codeanalyze.ChangeCollector(self.info.source)
+        definition = extract_info.definition
+        lineno, indents = extract_info.definition_location
+        offset = self.info.lines.get_line_start(lineno)
+        indented = sourceutils.fix_indentation(definition, indents)
+        content.add_change(offset, offset, indented)
+        self._replace_occurrences(content, extract_info)
+        return content.get_changed()
+
+    def _replace_occurrences(self, content, extract_info):
+        for match in extract_info.matches:
+            replacement = similarfinder.CodeTemplate(
+                extract_info.replacement_pattern)
+            mapping = {}
+            for name in replacement.get_names():
+                node = match.get_ast(name)
+                if node:
+                    start, end = patchedast.node_region(match.get_ast(name))
+                    mapping[name] = self.info.source[start:end]
+                else:
+                    mapping[name] = name
+            region = match.get_region()
+            content.add_change(region[0], region[1],
+                               replacement.substitute(mapping))
+
+    def _collect_info(self):
+        extract_collector = _ExtractCollector(self.info)
+        self._find_definition(extract_collector)
+        self._find_matches(extract_collector)
+        self._find_definition_location(extract_collector)
+        return extract_collector
+
+    def _find_matches(self, collector):
+        regions = self._where_to_search()
+        finder = similarfinder.SimilarFinder(self.info.pymodule)
+        matches = []
+        for start, end in regions:
+            matches.extend((finder.get_matches(collector.body_pattern,
+                                               collector.checks, start, end)))
+        collector.matches = matches
+
+    def _where_to_search(self):
+        if self.info.similar:
+            if self.info.make_global or self.info.global_:
+                return [(0, len(self.info.pymodule.source_code))]
+            if self.info.method and not self.info.variable:
+                class_scope = self.info.scope.parent
+                regions = []
+                method_kind = _get_function_kind(self.info.scope)
+                for scope in class_scope.get_scopes():
+                    if method_kind == 'method' and \
+                       _get_function_kind(scope) != 'method':
+                        continue
+                    start = self.info.lines.get_line_start(scope.get_start())
+                    end = self.info.lines.get_line_end(scope.get_end())
+                    regions.append((start, end))
+                return regions
+            else:
+                if self.info.variable:
+                    return [self.info.scope_region]
+                else:
+                    return [self.info._get_scope_region(self.info.scope.parent)]
+        else:
+            return [self.info.region]
+
+    def _find_definition_location(self, collector):
+        matched_lines = []
+        for match in collector.matches:
+            start = self.info.lines.get_line_number(match.get_region()[0])
+            start_line = self.info.logical_lines.logical_line_in(start)[0]
+            matched_lines.append(start_line)
+        location_finder = _DefinitionLocationFinder(self.info, matched_lines)
+        collector.definition_location = (location_finder.find_lineno(),
+                                         location_finder.find_indents())
+
+    def _find_definition(self, collector):
+        if self.info.variable:
+            parts = _ExtractVariableParts(self.info)
+        else:
+            parts = _ExtractMethodParts(self.info)
+        collector.definition = parts.get_definition()
+        collector.body_pattern = parts.get_body_pattern()
+        collector.replacement_pattern = parts.get_replacement_pattern()
+        collector.checks = parts.get_checks()
+
+
+class _DefinitionLocationFinder(object):
+
+    def __init__(self, info, matched_lines):
+        self.info = info
+        self.matched_lines = matched_lines
+        # This only happens when subexpressions cannot be matched
+        if not matched_lines:
+            self.matched_lines.append(self.info.region_lines[0])
+
+    def find_lineno(self):
+        if self.info.variable and not self.info.make_global:
+            return self._get_before_line()
+        if self.info.make_global or self.info.global_:
+            toplevel = self._find_toplevel(self.info.scope)
+            ast = self.info.pymodule.get_ast()
+            newlines = sorted(self.matched_lines + [toplevel.get_end() + 1])
+            return suites.find_visible(ast, newlines)
+        return self._get_after_scope()
+
+    def _find_toplevel(self, scope):
+        toplevel = scope
+        if toplevel.parent is not None:
+            while toplevel.parent.parent is not None:
+                toplevel = toplevel.parent
+        return toplevel
+
+    def find_indents(self):
+        if self.info.variable and not self.info.make_global:
+            return sourceutils.get_indents(self.info.lines,
+                                           self._get_before_line())
+        else:
+            if self.info.global_ or self.info.make_global:
+                return 0
+        return self.info.scope_indents
+
+    def _get_before_line(self):
+        ast = self.info.scope.pyobject.get_ast()
+        return suites.find_visible(ast, self.matched_lines)
+
+    def _get_after_scope(self):
+        return self.info.scope.get_end() + 1
+
+
+class _ExceptionalConditionChecker(object):
+
+    def __call__(self, info):
+        self.base_conditions(info)
+        if info.one_line:
+            self.one_line_conditions(info)
+        else:
+            self.multi_line_conditions(info)
+
+    def base_conditions(self, info):
+        if info.region[1] > info.scope_region[1]:
+            raise RefactoringError('Bad region selected for extract method')
+        end_line = info.region_lines[1]
+        end_scope = info.global_scope.get_inner_scope_for_line(end_line)
+        if end_scope != info.scope and end_scope.get_end() != end_line:
+            raise RefactoringError('Bad region selected for extract method')
+        try:
+            extracted = info.source[info.region[0]:info.region[1]]
+            if info.one_line:
+                extracted = '(%s)' % extracted
+            if _UnmatchedBreakOrContinueFinder.has_errors(extracted):
+                raise RefactoringError('A break/continue without having a '
+                                       'matching for/while loop.')
+        except SyntaxError:
+            raise RefactoringError('Extracted piece should '
+                                   'contain complete statements.')
+
+    def one_line_conditions(self, info):
+        if self._is_region_on_a_word(info):
+            raise RefactoringError('Should extract complete statements.')
+        if info.variable and not info.one_line:
+            raise RefactoringError('Extract variable should not '
+                                   'span multiple lines.')
+
+    def multi_line_conditions(self, info):
+        node = _parse_text(info.source[info.region[0]:info.region[1]])
+        count = usefunction._return_count(node)
+        if count > 1:
+            raise RefactoringError('Extracted piece can have only one '
+                                   'return statement.')
+        if usefunction._yield_count(node):
+            raise RefactoringError('Extracted piece cannot '
+                                   'have yield statements.')
+        if count == 1 and not usefunction._returns_last(node):
+            raise RefactoringError('Return should be the last statement.')
+        if info.region != info.lines_region:
+            raise RefactoringError('Extracted piece should '
+                                   'contain complete statements.')
+
+    def _is_region_on_a_word(self, info):
+        if info.region[0] > 0 and self._is_on_a_word(info, info.region[0] - 1) or \
+           self._is_on_a_word(info, info.region[1] - 1):
+            return True
+
+    def _is_on_a_word(self, info, offset):
+        prev = info.source[offset]
+        if not (prev.isalnum() or prev == '_') or \
+           offset + 1 == len(info.source):
+            return False
+        next = info.source[offset + 1]
+        return next.isalnum() or next == '_'
+
+
+class _ExtractMethodParts(object):
+
+    def __init__(self, info):
+        self.info = info
+        self.info_collector = self._create_info_collector()
+
+    def get_definition(self):
+        if self.info.global_:
+            return '\n%s\n' % self._get_function_definition()
+        else:
+            return '\n%s' % self._get_function_definition()
+
+    def get_replacement_pattern(self):
+        variables = []
+        variables.extend(self._find_function_arguments())
+        variables.extend(self._find_function_returns())
+        return similarfinder.make_pattern(self._get_call(), variables)
+
+    def get_body_pattern(self):
+        variables = []
+        variables.extend(self._find_function_arguments())
+        variables.extend(self._find_function_returns())
+        variables.extend(self._find_temps())
+        return similarfinder.make_pattern(self._get_body(), variables)
+
+    def _get_body(self):
+        result = sourceutils.fix_indentation(self.info.extracted, 0)
+        if self.info.one_line:
+            result = '(%s)' % result
+        return result
+
+    def _find_temps(self):
+        return usefunction.find_temps(self.info.pycore.project,
+                                      self._get_body())
+
+    def get_checks(self):
+        if self.info.method and not self.info.make_global:
+            if _get_function_kind(self.info.scope) == 'method':
+                class_name = similarfinder._pydefined_to_str(
+                    self.info.scope.parent.pyobject)
+                return {self._get_self_name(): 'type=' + class_name}
+        return {}
+
+    def _create_info_collector(self):
+        zero = self.info.scope.get_start() - 1
+        start_line = self.info.region_lines[0] - zero
+        end_line = self.info.region_lines[1] - zero
+        info_collector = _FunctionInformationCollector(start_line, end_line,
+                                                       self.info.global_)
+        body = self.info.source[self.info.scope_region[0]:
+                                self.info.scope_region[1]]
+        node = _parse_text(body)
+        ast.walk(node, info_collector)
+        return info_collector
+
+    def _get_function_definition(self):
+        args = self._find_function_arguments()
+        returns = self._find_function_returns()
+        result = []
+        if self.info.method and not self.info.make_global and \
+           _get_function_kind(self.info.scope) != 'method':
+            result.append('@staticmethod\n')
+        result.append('def %s:\n' % self._get_function_signature(args))
+        unindented_body = self._get_unindented_function_body(returns)
+        indents = sourceutils.get_indent(self.info.pycore)
+        function_body = sourceutils.indent_lines(unindented_body, indents)
+        result.append(function_body)
+        definition = ''.join(result)
+
+        return definition + '\n'
+
+    def _get_function_signature(self, args):
+        args = list(args)
+        prefix = ''
+        if self._extracting_method():
+            self_name = self._get_self_name()
+            if self_name is None:
+                raise RefactoringError('Extracting a method from a function '
+                                       'with no self argument.')
+            if self_name in args:
+                args.remove(self_name)
+            args.insert(0, self_name)
+        return prefix + self.info.new_name + \
+               '(%s)' % self._get_comma_form(args)
+
+    def _extracting_method(self):
+        return self.info.method and not self.info.make_global and \
+               _get_function_kind(self.info.scope) == 'method'
+
+    def _get_self_name(self):
+        param_names = self.info.scope.pyobject.get_param_names()
+        if param_names:
+            return param_names[0]
+
+    def _get_function_call(self, args):
+        prefix = ''
+        if self.info.method and not self.info.make_global:
+            if _get_function_kind(self.info.scope) == 'method':
+                self_name = self._get_self_name()
+                if  self_name in args:
+                    args.remove(self_name)
+                prefix = self_name + '.'
+            else:
+                prefix = self.info.scope.parent.pyobject.get_name() + '.'
+        return prefix + '%s(%s)' % (self.info.new_name,
+                                    self._get_comma_form(args))
+
+    def _get_comma_form(self, names):
+        result = ''
+        if names:
+            result += names[0]
+            for name in names[1:]:
+                result += ', ' + name
+        return result
+
+    def _get_call(self):
+        if self.info.one_line:
+            args = self._find_function_arguments()
+            return self._get_function_call(args)
+        args = self._find_function_arguments()
+        returns = self._find_function_returns()
+        call_prefix = ''
+        if returns:
+            call_prefix = self._get_comma_form(returns) + ' = '
+        if self.info.returned:
+            call_prefix = 'return '
+        return call_prefix + self._get_function_call(args)
+
+    def _find_function_arguments(self):
+        # if not make_global, do not pass any global names; they are
+        # all visible.
+        if self.info.global_ and not self.info.make_global:
+            return ()
+        if not self.info.one_line:
+            result = (self.info_collector.prewritten &
+                      self.info_collector.read)
+            result |= (self.info_collector.prewritten &
+                       self.info_collector.postread &
+                       (self.info_collector.maybe_written -
+                        self.info_collector.written))
+            return list(result)
+        start = self.info.region[0]
+        if start == self.info.lines_region[0]:
+            start = start + re.search('\S', self.info.extracted).start()
+        function_definition = self.info.source[start:self.info.region[1]]
+        read = _VariableReadsAndWritesFinder.find_reads_for_one_liners(
+            function_definition)
+        return list(self.info_collector.prewritten.intersection(read))
+
+    def _find_function_returns(self):
+        if self.info.one_line or self.info.returned:
+            return []
+        written = self.info_collector.written | \
+                  self.info_collector.maybe_written
+        return list(written & self.info_collector.postread)
+
+    def _get_unindented_function_body(self, returns):
+        if self.info.one_line:
+            return 'return ' + _join_lines(self.info.extracted)
+        extracted_body = self.info.extracted
+        unindented_body = sourceutils.fix_indentation(extracted_body, 0)
+        if returns:
+            unindented_body += '\nreturn %s' % self._get_comma_form(returns)
+        return unindented_body
+
+
+class _ExtractVariableParts(object):
+
+    def __init__(self, info):
+        self.info = info
+
+    def get_definition(self):
+        result = self.info.new_name + ' = ' + \
+                 _join_lines(self.info.extracted) + '\n'
+        return result
+
+    def get_body_pattern(self):
+        return '(%s)' % self.info.extracted.strip()
+
+    def get_replacement_pattern(self):
+        return self.info.new_name
+
+    def get_checks(self):
+        return {}
+
+
+class _FunctionInformationCollector(object):
+
+    def __init__(self, start, end, is_global):
+        self.start = start
+        self.end = end
+        self.is_global = is_global
+        self.prewritten = set()
+        self.maybe_written = set()
+        self.written = set()
+        self.read = set()
+        self.postread = set()
+        self.postwritten = set()
+        self.host_function = True
+        self.conditional = False
+
+    def _read_variable(self, name, lineno):
+        if self.start <= lineno <= self.end:
+            if name not in self.written:
+                self.read.add(name)
+        if self.end < lineno:
+            if name not in self.postwritten:
+                self.postread.add(name)
+
+    def _written_variable(self, name, lineno):
+        if self.start <= lineno <= self.end:
+            if self.conditional:
+                self.maybe_written.add(name)
+            else:
+                self.written.add(name)
+        if self.start > lineno:
+            self.prewritten.add(name)
+        if self.end < lineno:
+            self.postwritten.add(name)
+
+    def _FunctionDef(self, node):
+        if not self.is_global and self.host_function:
+            self.host_function = False
+            for name in _get_argnames(node.args):
+                self._written_variable(name, node.lineno)
+            for child in node.body:
+                ast.walk(child, self)
+        else:
+            self._written_variable(node.name, node.lineno)
+            visitor = _VariableReadsAndWritesFinder()
+            for child in node.body:
+                ast.walk(child, visitor)
+            for name in visitor.read - visitor.written:
+                self._read_variable(name, node.lineno)
+
+    def _Name(self, node):
+        if isinstance(node.ctx, (ast.Store, ast.AugStore)):
+            self._written_variable(node.id, node.lineno)
+        if not isinstance(node.ctx, ast.Store):
+            self._read_variable(node.id, node.lineno)
+
+    def _Assign(self, node):
+        ast.walk(node.value, self)
+        for child in node.targets:
+            ast.walk(child, self)
+
+    def _ClassDef(self, node):
+        self._written_variable(node.name, node.lineno)
+
+    def _handle_conditional_node(self, node):
+        self.conditional = True
+        try:
+            for child in ast.get_child_nodes(node):
+                ast.walk(child, self)
+        finally:
+            self.conditional = False
+
+    def _If(self, node):
+        self._handle_conditional_node(node)
+
+    def _While(self, node):
+        self._handle_conditional_node(node)
+
+    def _For(self, node):
+        self._handle_conditional_node(node)
+
+
+
+def _get_argnames(arguments):
+    result = [node.id for node in arguments.args
+              if isinstance(node, ast.Name)]
+    if arguments.vararg:
+        result.append(arguments.vararg)
+    if arguments.kwarg:
+        result.append(arguments.kwarg)
+    return result
+
+
+class _VariableReadsAndWritesFinder(object):
+
+    def __init__(self):
+        self.written = set()
+        self.read = set()
+
+    def _Name(self, node):
+        if isinstance(node.ctx, (ast.Store, ast.AugStore)):
+            self.written.add(node.id)
+        if not isinstance(node, ast.Store):
+            self.read.add(node.id)
+
+    def _FunctionDef(self, node):
+        self.written.add(node.name)
+        visitor = _VariableReadsAndWritesFinder()
+        for child in ast.get_child_nodes(node):
+            ast.walk(child, visitor)
+        self.read.update(visitor.read - visitor.written)
+
+    def _Class(self, node):
+        self.written.add(node.name)
+
+    @staticmethod
+    def find_reads_and_writes(code):
+        if code.strip() == '':
+            return set(), set()
+        if isinstance(code, unicode):
+            code = code.encode('utf-8')
+        node = _parse_text(code)
+        visitor = _VariableReadsAndWritesFinder()
+        ast.walk(node, visitor)
+        return visitor.read, visitor.written
+
+    @staticmethod
+    def find_reads_for_one_liners(code):
+        if code.strip() == '':
+            return set(), set()
+        node = _parse_text(code)
+        visitor = _VariableReadsAndWritesFinder()
+        ast.walk(node, visitor)
+        return visitor.read
+
+
+class _UnmatchedBreakOrContinueFinder(object):
+
+    def __init__(self):
+        self.error = False
+        self.loop_count = 0
+
+    def _For(self, node):
+        self.loop_encountered(node)
+
+    def _While(self, node):
+        self.loop_encountered(node)
+
+    def loop_encountered(self, node):
+        self.loop_count += 1
+        for child in node.body:
+            ast.walk(child, self)
+        self.loop_count -= 1
+        if node.orelse:
+            ast.walk(node.orelse, self)
+
+    def _Break(self, node):
+        self.check_loop()
+
+    def _Continue(self, node):
+        self.check_loop()
+
+    def check_loop(self):
+        if self.loop_count < 1:
+            self.error = True
+
+    def _FunctionDef(self, node):
+        pass
+
+    def _ClassDef(self, node):
+        pass
+
+    @staticmethod
+    def has_errors(code):
+        if code.strip() == '':
+            return False
+        node = _parse_text(code)
+        visitor = _UnmatchedBreakOrContinueFinder()
+        ast.walk(node, visitor)
+        return visitor.error
+
+def _get_function_kind(scope):
+    return scope.pyobject.get_kind()
+
+
+def _parse_text(body):
+    body = sourceutils.fix_indentation(body, 0)
+    node = ast.parse(body)
+    return node
+
+def _join_lines(code):
+    lines = []
+    for line in code.splitlines():
+        if line.endswith('\\'):
+            lines.append(line[:-1].strip())
+        else:
+            lines.append(line.strip())
+    return ' '.join(lines)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/functionutils.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,222 @@
+import rope.base.exceptions
+import rope.base.pyobjects
+from rope.base.builtins import Lambda
+from rope.base import worder
+
+
+class DefinitionInfo(object):
+
+    def __init__(self, function_name, is_method, args_with_defaults,
+                 args_arg, keywords_arg):
+        self.function_name = function_name
+        self.is_method = is_method
+        self.args_with_defaults = args_with_defaults
+        self.args_arg = args_arg
+        self.keywords_arg = keywords_arg
+
+    def to_string(self):
+        return '%s(%s)' % (self.function_name, self.arguments_to_string())
+
+    def arguments_to_string(self, from_index=0):
+        params = []
+        for arg, default in self.args_with_defaults:
+            if default is not None:
+                params.append('%s=%s' % (arg, default))
+            else:
+                params.append(arg)
+        if self.args_arg is not None:
+            params.append('*' + self.args_arg)
+        if self.keywords_arg:
+            params.append('**' + self.keywords_arg)
+        return ', '.join(params[from_index:])
+
+    @staticmethod
+    def _read(pyfunction, code):
+        scope = pyfunction.get_scope()
+        parent = scope.parent
+        parameter_names = pyfunction.get_param_names()
+        kind = pyfunction.get_kind()
+        is_method = kind == 'method'
+        is_lambda = kind == 'lambda'
+        info = _FunctionParser(code, is_method, is_lambda)
+        args, keywords = info.get_parameters()
+        args_arg = None
+        keywords_arg = None
+        if args and args[-1].startswith('**'):
+            keywords_arg = args[-1][2:]
+            del args[-1]
+        if args and args[-1].startswith('*'):
+            args_arg = args[-1][1:]
+            del args[-1]
+        args_with_defaults = [(name, None) for name in args]
+        args_with_defaults.extend(keywords)
+        return DefinitionInfo(info.get_function_name(), is_method,
+                              args_with_defaults, args_arg, keywords_arg)
+
+    @staticmethod
+    def read(pyfunction):
+        pymodule = pyfunction.get_module()
+        word_finder = worder.Worder(pymodule.source_code)
+        lineno = pyfunction.get_ast().lineno
+        start = pymodule.lines.get_line_start(lineno)
+        if isinstance(pyfunction, Lambda):
+            call = word_finder.get_lambda_and_args(start)
+        else:
+            call = word_finder.get_function_and_args_in_header(start)
+        return DefinitionInfo._read(pyfunction, call)
+
+
+class CallInfo(object):
+
+    def __init__(self, function_name, args, keywords, args_arg,
+                 keywords_arg, implicit_arg, constructor):
+        self.function_name = function_name
+        self.args = args
+        self.keywords = keywords
+        self.args_arg = args_arg
+        self.keywords_arg = keywords_arg
+        self.implicit_arg = implicit_arg
+        self.constructor = constructor
+
+    def to_string(self):
+        function = self.function_name
+        if self.implicit_arg:
+            function = self.args[0] + '.' + self.function_name
+        params = []
+        start = 0
+        if self.implicit_arg or self.constructor:
+            start = 1
+        if self.args[start:]:
+            params.extend(self.args[start:])
+        if self.keywords:
+            params.extend(['%s=%s' % (name, value) for name, value in self.keywords])
+        if self.args_arg is not None:
+            params.append('*' + self.args_arg)
+        if self.keywords_arg:
+            params.append('**' + self.keywords_arg)
+        return '%s(%s)' % (function, ', '.join(params))
+
+    @staticmethod
+    def read(primary, pyname, definition_info, code):
+        is_method_call = CallInfo._is_method_call(primary, pyname)
+        is_constructor = CallInfo._is_class(pyname)
+        is_classmethod = CallInfo._is_classmethod(pyname)
+        info = _FunctionParser(code, is_method_call or is_classmethod)
+        args, keywords = info.get_parameters()
+        args_arg = None
+        keywords_arg = None
+        if args and args[-1].startswith('**'):
+            keywords_arg = args[-1][2:]
+            del args[-1]
+        if args and args[-1].startswith('*'):
+            args_arg = args[-1][1:]
+            del args[-1]
+        if is_constructor:
+            args.insert(0, definition_info.args_with_defaults[0][0])
+        return CallInfo(info.get_function_name(), args, keywords, args_arg,
+                        keywords_arg, is_method_call or is_classmethod,
+                        is_constructor)
+
+    @staticmethod
+    def _is_method_call(primary, pyname):
+        return primary is not None and \
+               isinstance(primary.get_object().get_type(),
+                          rope.base.pyobjects.PyClass) and \
+                          CallInfo._is_method(pyname)
+
+    @staticmethod
+    def _is_class(pyname):
+        return pyname is not None and \
+               isinstance(pyname.get_object(),
+                          rope.base.pyobjects.PyClass)
+
+    @staticmethod
+    def _is_method(pyname):
+        if pyname is not None and \
+           isinstance(pyname.get_object(), rope.base.pyobjects.PyFunction):
+            return pyname.get_object().get_kind() == 'method'
+        return False
+
+    @staticmethod
+    def _is_classmethod(pyname):
+        if pyname is not None and \
+           isinstance(pyname.get_object(), rope.base.pyobjects.PyFunction):
+            return pyname.get_object().get_kind() == 'classmethod'
+        return False
+
+
+class ArgumentMapping(object):
+
+    def __init__(self, definition_info, call_info):
+        self.call_info = call_info
+        self.param_dict = {}
+        self.keyword_args = []
+        self.args_arg = []
+        for index, value in enumerate(call_info.args):
+            if index < len(definition_info.args_with_defaults):
+                name = definition_info.args_with_defaults[index][0]
+                self.param_dict[name] = value
+            else:
+                self.args_arg.append(value)
+        for name, value in call_info.keywords:
+            index = -1
+            for pair in definition_info.args_with_defaults:
+                if pair[0] == name:
+                    self.param_dict[name] = value
+                    break
+            else:
+                self.keyword_args.append((name, value))
+
+    def to_call_info(self, definition_info):
+        args = []
+        keywords = []
+        for index in range(len(definition_info.args_with_defaults)):
+            name = definition_info.args_with_defaults[index][0]
+            if name in self.param_dict:
+                args.append(self.param_dict[name])
+            else:
+                for i in range(index, len(definition_info.args_with_defaults)):
+                    name = definition_info.args_with_defaults[i][0]
+                    if name in self.param_dict:
+                        keywords.append((name, self.param_dict[name]))
+                break
+        args.extend(self.args_arg)
+        keywords.extend(self.keyword_args)
+        return CallInfo(self.call_info.function_name, args, keywords,
+                        self.call_info.args_arg, self.call_info.keywords_arg,
+                        self.call_info.implicit_arg, self.call_info.constructor)
+
+
+class _FunctionParser(object):
+
+    def __init__(self, call, implicit_arg, is_lambda=False):
+        self.call = call
+        self.implicit_arg = implicit_arg
+        self.word_finder = worder.Worder(self.call)
+        if is_lambda:
+            self.last_parens = self.call.rindex(':')
+        else:
+            self.last_parens = self.call.rindex(')')
+        self.first_parens = self.word_finder._find_parens_start(self.last_parens)
+
+    def get_parameters(self):
+        args, keywords = self.word_finder.get_parameters(self.first_parens,
+                                                         self.last_parens)
+        if self.is_called_as_a_method():
+            instance = self.call[:self.call.rindex('.', 0, self.first_parens)]
+            args.insert(0, instance.strip())
+        return args, keywords
+
+    def get_instance(self):
+        if self.is_called_as_a_method():
+            return self.word_finder.get_primary_at(
+                self.call.rindex('.', 0, self.first_parens) - 1)
+
+    def get_function_name(self):
+        if self.is_called_as_a_method():
+            return self.word_finder.get_word_at(self.first_parens - 1)
+        else:
+            return self.word_finder.get_primary_at(self.first_parens - 1)
+
+    def is_called_as_a_method(self):
+        return self.implicit_arg and '.' in self.call[:self.first_parens]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/importutils/__init__.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,299 @@
+"""A package for handling imports
+
+This package provides tools for modifying module imports after
+refactorings or as a separate task.
+
+"""
+import rope.base.evaluate
+from rope.base.change import ChangeSet, ChangeContents
+from rope.refactor import occurrences, rename
+from rope.refactor.importutils import module_imports, actions
+from rope.refactor.importutils.importinfo import NormalImport, FromImport
+import rope.base.codeanalyze
+
+
+class ImportOrganizer(object):
+    """Perform some import-related commands
+
+    Each method returns a `rope.base.change.Change` object.
+
+    """
+
+    def __init__(self, project):
+        self.project = project
+        self.pycore = project.pycore
+        self.import_tools = ImportTools(self.pycore)
+
+    def organize_imports(self, resource, offset=None):
+        return self._perform_command_on_import_tools(
+            self.import_tools.organize_imports, resource, offset)
+
+    def expand_star_imports(self, resource, offset=None):
+        return self._perform_command_on_import_tools(
+            self.import_tools.expand_stars, resource, offset)
+
+    def froms_to_imports(self, resource, offset=None):
+        return self._perform_command_on_import_tools(
+            self.import_tools.froms_to_imports, resource, offset)
+
+    def relatives_to_absolutes(self, resource, offset=None):
+        return self._perform_command_on_import_tools(
+            self.import_tools.relatives_to_absolutes, resource, offset)
+
+    def handle_long_imports(self, resource, offset=None):
+        return self._perform_command_on_import_tools(
+            self.import_tools.handle_long_imports, resource, offset)
+
+    def _perform_command_on_import_tools(self, method, resource, offset):
+        pymodule = self.pycore.resource_to_pyobject(resource)
+        before_performing = pymodule.source_code
+        import_filter = None
+        if offset is not None:
+            import_filter = self._line_filter(
+                pymodule.lines.get_line_number(offset))
+        result = method(pymodule, import_filter=import_filter)
+        if result is not None and result != before_performing:
+            changes = ChangeSet(method.__name__.replace('_', ' ') +
+                                ' in <%s>' % resource.path)
+            changes.add_change(ChangeContents(resource, result))
+            return changes
+
+    def _line_filter(self, lineno):
+        def import_filter(import_stmt):
+            return import_stmt.start_line <= lineno < import_stmt.end_line
+        return import_filter
+
+
+class ImportTools(object):
+
+    def __init__(self, pycore):
+        self.pycore = pycore
+
+    def get_import(self, resource):
+        """The import statement for `resource`"""
+        module_name = self.pycore.modname(resource)
+        return NormalImport(((module_name, None), ))
+
+    def get_from_import(self, resource, name):
+        """The from import statement for `name` in `resource`"""
+        module_name = self.pycore.modname(resource)
+        names = []
+        if isinstance(name, list):
+            names = [(imported, None) for imported in name]
+        else:
+            names = [(name, None),]
+        return FromImport(module_name, 0, tuple(names))
+
+    def module_imports(self, module, imports_filter=None):
+        return module_imports.ModuleImports(self.pycore, module,
+                                            imports_filter)
+
+    def froms_to_imports(self, pymodule, import_filter=None):
+        pymodule = self._clean_up_imports(pymodule, import_filter)
+        module_imports = self.module_imports(pymodule, import_filter)
+        for import_stmt in module_imports.imports:
+            if import_stmt.readonly or \
+               not self._is_transformable_to_normal(import_stmt.import_info):
+                continue
+            pymodule = self._from_to_normal(pymodule, import_stmt)
+
+        # Adding normal imports in place of froms
+        module_imports = self.module_imports(pymodule, import_filter)
+        for import_stmt in module_imports.imports:
+            if not import_stmt.readonly and \
+               self._is_transformable_to_normal(import_stmt.import_info):
+                import_stmt.import_info = \
+                    NormalImport(((import_stmt.import_info.module_name, None),))
+        module_imports.remove_duplicates()
+        return module_imports.get_changed_source()
+
+    def expand_stars(self, pymodule, import_filter=None):
+        module_imports = self.module_imports(pymodule, import_filter)
+        module_imports.expand_stars()
+        return module_imports.get_changed_source()
+
+    def _from_to_normal(self, pymodule, import_stmt):
+        resource = pymodule.get_resource()
+        from_import = import_stmt.import_info
+        module_name = from_import.module_name
+        for name, alias in from_import.names_and_aliases:
+            imported = name
+            if alias is not None:
+                imported = alias
+            occurrence_finder = occurrences.create_finder(
+                self.pycore, imported, pymodule[imported], imports=False)
+            source = rename.rename_in_module(
+                occurrence_finder, module_name + '.' + name,
+                pymodule=pymodule, replace_primary=True)
+            if source is not None:
+                pymodule = self.pycore.get_string_module(source, resource)
+        return pymodule
+
+    def _clean_up_imports(self, pymodule, import_filter):
+        resource = pymodule.get_resource()
+        module_with_imports = self.module_imports(pymodule, import_filter)
+        module_with_imports.expand_stars()
+        source = module_with_imports.get_changed_source()
+        if source is not None:
+            pymodule = self.pycore.get_string_module(source, resource)
+        source = self.relatives_to_absolutes(pymodule)
+        if source is not None:
+            pymodule = self.pycore.get_string_module(source, resource)
+
+        module_with_imports = self.module_imports(pymodule, import_filter)
+        module_with_imports.remove_duplicates()
+        module_with_imports.remove_unused_imports()
+        source = module_with_imports.get_changed_source()
+        if source is not None:
+            pymodule = self.pycore.get_string_module(source, resource)
+        return pymodule
+
+    def relatives_to_absolutes(self, pymodule, import_filter=None):
+        module_imports = self.module_imports(pymodule, import_filter)
+        to_be_absolute_list = module_imports.get_relative_to_absolute_list()
+        for name, absolute_name in to_be_absolute_list:
+            pymodule = self._rename_in_module(pymodule, name, absolute_name)
+        module_imports = self.module_imports(pymodule, import_filter)
+        module_imports.get_relative_to_absolute_list()
+        source = module_imports.get_changed_source()
+        if source is None:
+            source = pymodule.source_code
+        return source
+
+    def _is_transformable_to_normal(self, import_info):
+        if not isinstance(import_info, FromImport):
+            return False
+        return True
+
+    def organize_imports(self, pymodule,
+                         unused=True, duplicates=True,
+                         selfs=True, sort=True, import_filter=None):
+        if unused or duplicates:
+            module_imports = self.module_imports(pymodule, import_filter)
+            if unused:
+                module_imports.remove_unused_imports()
+            if duplicates:
+                module_imports.remove_duplicates()
+            source = module_imports.get_changed_source()
+            if source is not None:
+                pymodule = self.pycore.get_string_module(
+                    source, pymodule.get_resource())
+        if selfs:
+            pymodule = self._remove_self_imports(pymodule, import_filter)
+        if sort:
+            return self.sort_imports(pymodule, import_filter)
+        else:
+            return pymodule.source_code
+
+    def _remove_self_imports(self, pymodule, import_filter=None):
+        module_imports = self.module_imports(pymodule, import_filter)
+        to_be_fixed, to_be_renamed = module_imports.get_self_import_fix_and_rename_list()
+        for name in to_be_fixed:
+            try:
+                pymodule = self._rename_in_module(pymodule, name, '', till_dot=True)
+            except ValueError:
+                # There is a self import with direct access to it
+                return pymodule
+        for name, new_name in to_be_renamed:
+            pymodule = self._rename_in_module(pymodule, name, new_name)
+        module_imports = self.module_imports(pymodule, import_filter)
+        module_imports.get_self_import_fix_and_rename_list()
+        source = module_imports.get_changed_source()
+        if source is not None:
+            pymodule = self.pycore.get_string_module(source, pymodule.get_resource())
+        return pymodule
+
+    def _rename_in_module(self, pymodule, name, new_name, till_dot=False):
+        old_name = name.split('.')[-1]
+        old_pyname = rope.base.evaluate.eval_str(pymodule.get_scope(), name)
+        occurrence_finder = occurrences.create_finder(
+            self.pycore, old_name, old_pyname, imports=False)
+        changes = rope.base.codeanalyze.ChangeCollector(pymodule.source_code)
+        for occurrence in occurrence_finder.find_occurrences(pymodule=pymodule):
+            start, end = occurrence.get_primary_range()
+            if till_dot:
+                new_end = pymodule.source_code.index('.', end) + 1
+                space = pymodule.source_code[end:new_end - 1].strip()
+                if not space == '':
+                    for c in space:
+                        if not c.isspace() and c not in '\\':
+                            raise ValueError()
+                end = new_end
+            changes.add_change(start, end, new_name)
+        source = changes.get_changed()
+        if source is not None:
+            pymodule = self.pycore.get_string_module(source, pymodule.get_resource())
+        return pymodule
+
+    def sort_imports(self, pymodule, import_filter=None):
+        module_imports = self.module_imports(pymodule, import_filter)
+        module_imports.sort_imports()
+        return module_imports.get_changed_source()
+
+    def handle_long_imports(self, pymodule, maxdots=2, maxlength=27,
+                            import_filter=None):
+        # IDEA: `maxdots` and `maxlength` can be specified in project config
+        # adding new from imports
+        module_imports = self.module_imports(pymodule, import_filter)
+        to_be_fixed = module_imports.handle_long_imports(maxdots, maxlength)
+        # performing the renaming
+        pymodule = self.pycore.get_string_module(
+            module_imports.get_changed_source(),
+            resource=pymodule.get_resource())
+        for name in to_be_fixed:
+            pymodule = self._rename_in_module(pymodule, name,
+                                              name.split('.')[-1])
+        # organizing imports
+        return self.organize_imports(pymodule, selfs=False, sort=False,
+                                     import_filter=import_filter)
+
+
+def get_imports(pycore, pydefined):
+    """A shortcut for getting the `ImportInfo`\s used in a scope"""
+    pymodule = pydefined.get_module()
+    module = module_imports.ModuleImports(pycore, pymodule)
+    if pymodule == pydefined:
+        return [stmt.import_info for stmt in module.imports]
+    return module.get_used_imports(pydefined)
+
+
+def get_module_imports(pycore, pymodule):
+    """A shortcut for creating a `module_imports.ModuleImports` object"""
+    return module_imports.ModuleImports(pycore, pymodule)
+
+
+def add_import(pycore, pymodule, module_name, name=None):
+    imports = get_module_imports(pycore, pymodule)
+    candidates = []
+    names = []
+    # from mod import name
+    if name is not None:
+        from_import = FromImport(module_name, 0, [(name, None)])
+        names.append(name)
+        candidates.append(from_import)
+    # from pkg import mod
+    if '.' in module_name:
+        pkg, mod = module_name.rsplit('.', 1)
+        candidates.append(FromImport(pkg, 0, [(mod, None)]))
+        if name:
+            names.append(mod + '.' + name)
+        else:
+            names.append(mod)
+    # import mod
+    normal_import = NormalImport([(module_name, None)])
+    if name:
+        names.append(module_name + '.' + name)
+    else:
+        names.append(module_name)
+
+    candidates.append(normal_import)
+
+    visitor = actions.AddingVisitor(pycore, candidates)
+    selected_import = normal_import
+    for import_statement in imports.imports:
+        if import_statement.accept(visitor):
+            selected_import = visitor.import_info
+            break
+    imports.add_import(selected_import)
+    imported_name = names[candidates.index(selected_import)]
+    return imports.get_changed_source(), imported_name
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/importutils/actions.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,359 @@
+import os
+import sys
+
+from rope.base import pyobjects, exceptions, stdmods
+from rope.refactor import occurrences
+from rope.refactor.importutils import importinfo
+
+
+class ImportInfoVisitor(object):
+
+    def dispatch(self, import_):
+        try:
+            method_name = 'visit' + import_.import_info.__class__.__name__
+            method = getattr(self, method_name)
+            return method(import_, import_.import_info)
+        except exceptions.ModuleNotFoundError:
+            pass
+
+    def visitEmptyImport(self, import_stmt, import_info):
+        pass
+
+    def visitNormalImport(self, import_stmt, import_info):
+        pass
+
+    def visitFromImport(self, import_stmt, import_info):
+        pass
+
+
+class RelativeToAbsoluteVisitor(ImportInfoVisitor):
+
+    def __init__(self, pycore, current_folder):
+        self.to_be_absolute = []
+        self.pycore = pycore
+        self.folder = current_folder
+        self.context = importinfo.ImportContext(pycore, current_folder)
+
+    def visitNormalImport(self, import_stmt, import_info):
+        self.to_be_absolute.extend(self._get_relative_to_absolute_list(import_info))
+        new_pairs = []
+        for name, alias in import_info.names_and_aliases:
+            resource = self.pycore.find_module(name, folder=self.folder)
+            if resource is None:
+                new_pairs.append((name, alias))
+                continue
+            absolute_name = self.pycore.modname(resource)
+            new_pairs.append((absolute_name, alias))
+        if not import_info._are_name_and_alias_lists_equal(
+            new_pairs, import_info.names_and_aliases):
+            import_stmt.import_info = importinfo.NormalImport(new_pairs)
+
+    def _get_relative_to_absolute_list(self, import_info):
+        result = []
+        for name, alias in import_info.names_and_aliases:
+            if alias is not None:
+                continue
+            resource = self.pycore.find_module(name, folder=self.folder)
+            if resource is None:
+                continue
+            absolute_name = self.pycore.modname(resource)
+            if absolute_name != name:
+                result.append((name, absolute_name))
+        return result
+
+    def visitFromImport(self, import_stmt, import_info):
+        resource = import_info.get_imported_resource(self.context)
+        if resource is None:
+            return None
+        absolute_name = self.pycore.modname(resource)
+        if import_info.module_name != absolute_name:
+            import_stmt.import_info = importinfo.FromImport(
+                absolute_name, 0, import_info.names_and_aliases)
+
+
+class FilteringVisitor(ImportInfoVisitor):
+
+    def __init__(self, pycore, folder, can_select):
+        self.to_be_absolute = []
+        self.pycore = pycore
+        self.can_select = self._transform_can_select(can_select)
+        self.context = importinfo.ImportContext(pycore, folder)
+
+    def _transform_can_select(self, can_select):
+        def can_select_name_and_alias(name, alias):
+            imported = name
+            if alias is not None:
+                imported = alias
+            return can_select(imported)
+        return can_select_name_and_alias
+
+    def visitNormalImport(self, import_stmt, import_info):
+        new_pairs = []
+        for name, alias in import_info.names_and_aliases:
+            if self.can_select(name, alias):
+                new_pairs.append((name, alias))
+        return importinfo.NormalImport(new_pairs)
+
+    def visitFromImport(self, import_stmt, import_info):
+        if _is_future(import_info):
+            return import_info
+        new_pairs = []
+        if import_info.is_star_import():
+            for name in import_info.get_imported_names(self.context):
+                if self.can_select(name, None):
+                    new_pairs.append(import_info.names_and_aliases[0])
+                    break
+        else:
+            for name, alias in import_info.names_and_aliases:
+                if self.can_select(name, alias):
+                    new_pairs.append((name, alias))
+        return importinfo.FromImport(
+            import_info.module_name, import_info.level, new_pairs)
+
+
+class RemovingVisitor(ImportInfoVisitor):
+
+    def __init__(self, pycore, folder, can_select):
+        self.to_be_absolute = []
+        self.pycore = pycore
+        self.filtering = FilteringVisitor(pycore, folder, can_select)
+
+    def dispatch(self, import_):
+        result = self.filtering.dispatch(import_)
+        if result is not None:
+            import_.import_info = result
+
+
+class AddingVisitor(ImportInfoVisitor):
+    """A class for adding imports
+
+    Given a list of `ImportInfo`\s, it tries to add each import to the
+    module and returns `True` and gives up when an import can be added
+    to older ones.
+
+    """
+
+    def __init__(self, pycore, import_list):
+        self.pycore = pycore
+        self.import_list = import_list
+        self.import_info = None
+
+    def dispatch(self, import_):
+        for import_info in self.import_list:
+            self.import_info = import_info
+            if ImportInfoVisitor.dispatch(self, import_):
+                return True
+
+    # TODO: Handle adding relative and absolute imports
+    def visitNormalImport(self, import_stmt, import_info):
+        if not isinstance(self.import_info, import_info.__class__):
+            return False
+        # Adding ``import x`` and ``import x.y`` that results ``import x.y``
+        if len(import_info.names_and_aliases) == \
+           len(self.import_info.names_and_aliases) == 1:
+            imported1 = import_info.names_and_aliases[0]
+            imported2 = self.import_info.names_and_aliases[0]
+            if imported1[1] == imported2[1] is None:
+                if imported1[0].startswith(imported2[0] + '.'):
+                    return True
+                if imported2[0].startswith(imported1[0] + '.'):
+                    import_stmt.import_info = self.import_info
+                    return True
+        # Multiple imports using a single import statement is discouraged
+        # so we won't bother adding them.
+        if self.import_info._are_name_and_alias_lists_equal(
+            import_info.names_and_aliases, self.import_info.names_and_aliases):
+            return True
+
+    def visitFromImport(self, import_stmt, import_info):
+        if isinstance(self.import_info, import_info.__class__) and \
+           import_info.module_name == self.import_info.module_name and \
+           import_info.level == self.import_info.level:
+            if import_info.is_star_import():
+                return True
+            if self.import_info.is_star_import():
+                import_stmt.import_info = self.import_info
+                return True
+            new_pairs = list(import_info.names_and_aliases)
+            for pair in self.import_info.names_and_aliases:
+                if pair not in new_pairs:
+                    new_pairs.append(pair)
+            import_stmt.import_info = importinfo.FromImport(
+                import_info.module_name, import_info.level, new_pairs)
+            return True
+
+
+class ExpandStarsVisitor(ImportInfoVisitor):
+
+    def __init__(self, pycore, folder, can_select):
+        self.pycore = pycore
+        self.filtering = FilteringVisitor(pycore, folder, can_select)
+        self.context = importinfo.ImportContext(pycore, folder)
+
+    def visitNormalImport(self, import_stmt, import_info):
+        self.filtering.dispatch(import_stmt)
+
+    def visitFromImport(self, import_stmt, import_info):
+        if import_info.is_star_import():
+            new_pairs = []
+            for name in import_info.get_imported_names(self.context):
+                new_pairs.append((name, None))
+            new_import = importinfo.FromImport(
+                import_info.module_name, import_info.level, new_pairs)
+            import_stmt.import_info = \
+                self.filtering.visitFromImport(None, new_import)
+        else:
+            self.filtering.dispatch(import_stmt)
+
+
+class SelfImportVisitor(ImportInfoVisitor):
+
+    def __init__(self, pycore, current_folder, resource):
+        self.pycore = pycore
+        self.folder = current_folder
+        self.resource = resource
+        self.to_be_fixed = set()
+        self.to_be_renamed = set()
+        self.context = importinfo.ImportContext(pycore, current_folder)
+
+    def visitNormalImport(self, import_stmt, import_info):
+        new_pairs = []
+        for name, alias in import_info.names_and_aliases:
+            resource = self.pycore.find_module(name, folder=self.folder)
+            if resource is not None and resource == self.resource:
+                imported = name
+                if alias is not None:
+                    imported = alias
+                self.to_be_fixed.add(imported)
+            else:
+                new_pairs.append((name, alias))
+        if not import_info._are_name_and_alias_lists_equal(
+            new_pairs, import_info.names_and_aliases):
+            import_stmt.import_info = importinfo.NormalImport(new_pairs)
+
+    def visitFromImport(self, import_stmt, import_info):
+        resource = import_info.get_imported_resource(self.context)
+        if resource is None:
+            return
+        if resource == self.resource:
+            self._importing_names_from_self(import_info, import_stmt)
+            return
+        pymodule = self.pycore.resource_to_pyobject(resource)
+        new_pairs = []
+        for name, alias in import_info.names_and_aliases:
+            try:
+                result = pymodule[name].get_object()
+                if isinstance(result, pyobjects.PyModule) and \
+                   result.get_resource() == self.resource:
+                    imported = name
+                    if alias is not None:
+                        imported = alias
+                    self.to_be_fixed.add(imported)
+                else:
+                    new_pairs.append((name, alias))
+            except exceptions.AttributeNotFoundError:
+                new_pairs.append((name, alias))
+        if not import_info._are_name_and_alias_lists_equal(
+            new_pairs, import_info.names_and_aliases):
+            import_stmt.import_info = importinfo.FromImport(
+                import_info.module_name, import_info.level, new_pairs)
+
+    def _importing_names_from_self(self, import_info, import_stmt):
+        if not import_info.is_star_import():
+            for name, alias in import_info.names_and_aliases:
+                if alias is not None:
+                    self.to_be_renamed.add((alias, name))
+        import_stmt.empty_import()
+
+
+class SortingVisitor(ImportInfoVisitor):
+
+    def __init__(self, pycore, current_folder):
+        self.pycore = pycore
+        self.folder = current_folder
+        self.standard = set()
+        self.third_party = set()
+        self.in_project = set()
+        self.future = set()
+        self.context = importinfo.ImportContext(pycore, current_folder)
+
+    def visitNormalImport(self, import_stmt, import_info):
+        if import_info.names_and_aliases:
+            name, alias = import_info.names_and_aliases[0]
+            resource = self.pycore.find_module(
+                name, folder=self.folder)
+            self._check_imported_resource(import_stmt, resource, name)
+
+    def visitFromImport(self, import_stmt, import_info):
+        resource = import_info.get_imported_resource(self.context)
+        self._check_imported_resource(import_stmt, resource,
+                                      import_info.module_name)
+
+    def _check_imported_resource(self, import_stmt, resource, imported_name):
+        info = import_stmt.import_info
+        if resource is not None and resource.project == self.pycore.project:
+            self.in_project.add(import_stmt)
+        elif _is_future(info):
+            self.future.add(import_stmt)
+        elif imported_name.split('.')[0] in stdmods.standard_modules():
+            self.standard.add(import_stmt)
+        else:
+            self.third_party.add(import_stmt)
+
+
+class LongImportVisitor(ImportInfoVisitor):
+
+    def __init__(self, current_folder, pycore, maxdots, maxlength):
+        self.maxdots = maxdots
+        self.maxlength = maxlength
+        self.to_be_renamed = set()
+        self.current_folder = current_folder
+        self.pycore = pycore
+        self.new_imports = []
+
+    def visitNormalImport(self, import_stmt, import_info):
+        new_pairs = []
+        for name, alias in import_info.names_and_aliases:
+            if alias is None and self._is_long(name):
+                self.to_be_renamed.add(name)
+                last_dot = name.rindex('.')
+                from_ = name[:last_dot]
+                imported = name[last_dot + 1:]
+                self.new_imports.append(
+                    importinfo.FromImport(from_, 0, ((imported, None), )))
+
+    def _is_long(self, name):
+        return name.count('.') > self.maxdots or \
+               ('.' in name and len(name) > self.maxlength)
+
+
+class RemovePyNameVisitor(ImportInfoVisitor):
+
+    def __init__(self, pycore, pymodule, pyname, folder):
+        self.pymodule = pymodule
+        self.pyname = pyname
+        self.context = importinfo.ImportContext(pycore, folder)
+
+    def visitFromImport(self, import_stmt, import_info):
+        new_pairs = []
+        if not import_info.is_star_import():
+            for name, alias in import_info.names_and_aliases:
+                try:
+                    pyname = self.pymodule[alias or name]
+                    if occurrences.same_pyname(self.pyname, pyname):
+                        continue
+                except exceptions.AttributeNotFoundError:
+                    pass
+                new_pairs.append((name, alias))
+        return importinfo.FromImport(
+            import_info.module_name, import_info.level, new_pairs)
+
+    def dispatch(self, import_):
+        result = ImportInfoVisitor.dispatch(self, import_)
+        if result is not None:
+            import_.import_info = result
+
+
+def _is_future(info):
+    return isinstance(info, importinfo.FromImport) and \
+           info.module_name == '__future__'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/importutils/importinfo.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,201 @@
+class ImportStatement(object):
+    """Represent an import in a module
+
+    `readonly` attribute controls whether this import can be changed
+    by import actions or not.
+
+    """
+
+    def __init__(self, import_info, start_line, end_line,
+                 main_statement=None, blank_lines=0):
+        self.start_line = start_line
+        self.end_line = end_line
+        self.readonly = False
+        self.main_statement = main_statement
+        self._import_info = None
+        self.import_info = import_info
+        self._is_changed = False
+        self.new_start = None
+        self.blank_lines = blank_lines
+
+    def _get_import_info(self):
+        return self._import_info
+
+    def _set_import_info(self, new_import):
+        if not self.readonly and \
+           new_import is not None and not new_import == self._import_info:
+            self._is_changed = True
+            self._import_info = new_import
+
+    import_info = property(_get_import_info, _set_import_info)
+
+    def get_import_statement(self):
+        if self._is_changed or self.main_statement is None:
+            return self.import_info.get_import_statement()
+        else:
+            return self.main_statement
+
+    def empty_import(self):
+        self.import_info = ImportInfo.get_empty_import()
+
+    def move(self, lineno, blank_lines=0):
+        self.new_start = lineno
+        self.blank_lines = blank_lines
+
+    def get_old_location(self):
+        return self.start_line, self.end_line
+
+    def get_new_start(self):
+        return self.new_start
+
+    def is_changed(self):
+        return self._is_changed or (self.new_start is not None or
+                                    self.new_start != self.start_line)
+
+    def accept(self, visitor):
+        return visitor.dispatch(self)
+
+
+class ImportInfo(object):
+
+    def get_imported_primaries(self, context):
+        pass
+
+    def get_imported_names(self, context):
+        return [primary.split('.')[0]
+                for primary in self.get_imported_primaries(context)]
+
+    def get_import_statement(self):
+        pass
+
+    def is_empty(self):
+        pass
+
+    def __hash__(self):
+        return hash(self.get_import_statement())
+
+    def _are_name_and_alias_lists_equal(self, list1, list2):
+        if len(list1) != len(list2):
+            return False
+        for pair1, pair2 in zip(list1, list2):
+            if pair1 != pair2:
+                return False
+        return True
+
+    def __eq__(self, obj):
+        return isinstance(obj, self.__class__) and \
+               self.get_import_statement() == obj.get_import_statement()
+
+    def __ne__(self, obj):
+        return not self.__eq__(obj)
+
+    @staticmethod
+    def get_empty_import():
+        return EmptyImport()
+
+
+class NormalImport(ImportInfo):
+
+    def __init__(self, names_and_aliases):
+        self.names_and_aliases = names_and_aliases
+
+    def get_imported_primaries(self, context):
+        result = []
+        for name, alias in self.names_and_aliases:
+            if alias:
+                result.append(alias)
+            else:
+                result.append(name)
+        return result
+
+    def get_import_statement(self):
+        result = 'import '
+        for name, alias in self.names_and_aliases:
+            result += name
+            if alias:
+                result += ' as ' + alias
+            result += ', '
+        return result[:-2]
+
+    def is_empty(self):
+        return len(self.names_and_aliases) == 0
+
+
+class FromImport(ImportInfo):
+
+    def __init__(self, module_name, level, names_and_aliases):
+        self.module_name = module_name
+        self.level = level
+        self.names_and_aliases = names_and_aliases
+
+    def get_imported_primaries(self, context):
+        if self.names_and_aliases[0][0] == '*':
+            module = self.get_imported_module(context)
+            return [name for name in module
+                    if not name.startswith('_')]
+        result = []
+        for name, alias in self.names_and_aliases:
+            if alias:
+                result.append(alias)
+            else:
+                result.append(name)
+        return result
+
+    def get_imported_resource(self, context):
+        """Get the imported resource
+
+        Returns `None` if module was not found.
+        """
+        if self.level == 0:
+            return context.pycore.find_module(
+                self.module_name, folder=context.folder)
+        else:
+            return context.pycore.find_relative_module(
+                self.module_name, context.folder, self.level)
+
+    def get_imported_module(self, context):
+        """Get the imported `PyModule`
+
+        Raises `rope.base.exceptions.ModuleNotFoundError` if module
+        could not be found.
+        """
+        if self.level == 0:
+            return context.pycore.get_module(
+                self.module_name, context.folder)
+        else:
+            return context.pycore.get_relative_module(
+                self.module_name, context.folder, self.level)
+
+    def get_import_statement(self):
+        result = 'from ' + '.' * self.level + self.module_name + ' import '
+        for name, alias in self.names_and_aliases:
+            result += name
+            if alias:
+                result += ' as ' + alias
+            result += ', '
+        return result[:-2]
+
+    def is_empty(self):
+        return len(self.names_and_aliases) == 0
+
+    def is_star_import(self):
+        return len(self.names_and_aliases) > 0 and \
+               self.names_and_aliases[0][0] == '*'
+
+
+class EmptyImport(ImportInfo):
+
+    names_and_aliases = []
+
+    def is_empty(self):
+        return True
+
+    def get_imported_primaries(self, context):
+        return []
+
+
+class ImportContext(object):
+
+    def __init__(self, pycore, folder):
+        self.pycore = pycore
+        self.folder = folder
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/importutils/module_imports.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,454 @@
+import rope.base.pynames
+from rope.base import ast, utils
+from rope.refactor.importutils import importinfo
+from rope.refactor.importutils import actions
+
+
+class ModuleImports(object):
+
+    def __init__(self, pycore, pymodule, import_filter=None):
+        self.pycore = pycore
+        self.pymodule = pymodule
+        self.separating_lines = 0
+        self.filter = import_filter
+
+    @property
+    @utils.saveit
+    def imports(self):
+        finder = _GlobalImportFinder(self.pymodule, self.pycore)
+        result = finder.find_import_statements()
+        self.separating_lines = finder.get_separating_line_count()
+        if self.filter is not None:
+            for import_stmt in result:
+                if not self.filter(import_stmt):
+                    import_stmt.readonly = True
+        return result
+
+    def _get_unbound_names(self, defined_pyobject):
+        visitor = _GlobalUnboundNameFinder(self.pymodule, defined_pyobject)
+        ast.walk(self.pymodule.get_ast(), visitor)
+        return visitor.unbound
+
+    def remove_unused_imports(self):
+        can_select = _OneTimeSelector(self._get_unbound_names(self.pymodule))
+        visitor = actions.RemovingVisitor(
+            self.pycore, self._current_folder(), can_select)
+        for import_statement in self.imports:
+            import_statement.accept(visitor)
+
+    def get_used_imports(self, defined_pyobject):
+        result = []
+        can_select = _OneTimeSelector(self._get_unbound_names(defined_pyobject))
+        visitor = actions.FilteringVisitor(
+            self.pycore, self._current_folder(), can_select)
+        for import_statement in self.imports:
+            new_import = import_statement.accept(visitor)
+            if new_import is not None and not new_import.is_empty():
+                result.append(new_import)
+        return result
+
+    def get_changed_source(self):
+        imports = self.imports
+        after_removing = self._remove_imports(imports)
+        imports = [stmt for stmt in imports
+                   if not stmt.import_info.is_empty()]
+
+        first_non_blank = self._first_non_blank_line(after_removing, 0)
+        first_import = self._first_import_line() - 1
+        result = []
+        # Writing module docs
+        result.extend(after_removing[first_non_blank:first_import])
+        # Writing imports
+        sorted_imports = sorted(imports, self._compare_import_locations)
+        for stmt in sorted_imports:
+            start = self._get_import_location(stmt)
+            if stmt != sorted_imports[0]:
+                result.append('\n' * stmt.blank_lines)
+            result.append(stmt.get_import_statement() + '\n')
+        if sorted_imports and first_non_blank < len(after_removing):
+            result.append('\n' * self.separating_lines)
+
+        # Writing the body
+        first_after_imports = self._first_non_blank_line(after_removing,
+                                                         first_import)
+        result.extend(after_removing[first_after_imports:])
+        return ''.join(result)
+
+    def _get_import_location(self, stmt):
+        start = stmt.get_new_start()
+        if start is None:
+            start = stmt.get_old_location()[0]
+        return start
+
+    def _compare_import_locations(self, stmt1, stmt2):
+        def get_location(stmt):
+            if stmt.get_new_start() is not None:
+                return stmt.get_new_start()
+            else:
+                return stmt.get_old_location()[0]
+        return cmp(get_location(stmt1), get_location(stmt2))
+
+    def _remove_imports(self, imports):
+        lines = self.pymodule.source_code.splitlines(True)
+        after_removing = []
+        last_index = 0
+        for stmt in imports:
+            start, end = stmt.get_old_location()
+            after_removing.extend(lines[last_index:start - 1])
+            last_index = end - 1
+            for i in range(start, end):
+                after_removing.append('')
+        after_removing.extend(lines[last_index:])
+        return after_removing
+
+    def _first_non_blank_line(self, lines, lineno):
+        result = lineno
+        for line in lines[lineno:]:
+            if line.strip() == '':
+                result += 1
+            else:
+                break
+        return result
+
+    def add_import(self, import_info):
+        visitor = actions.AddingVisitor(self.pycore, [import_info])
+        for import_statement in self.imports:
+            if import_statement.accept(visitor):
+                break
+        else:
+            lineno = self._get_new_import_lineno()
+            blanks = self._get_new_import_blanks()
+            self.imports.append(importinfo.ImportStatement(
+                                import_info, lineno, lineno,
+                                blank_lines=blanks))
+
+    def _get_new_import_blanks(self):
+        return 0
+
+    def _get_new_import_lineno(self):
+        if self.imports:
+            return self.imports[-1].end_line
+        return 1
+
+    def filter_names(self, can_select):
+        visitor = actions.RemovingVisitor(
+            self.pycore, self._current_folder(), can_select)
+        for import_statement in self.imports:
+            import_statement.accept(visitor)
+
+    def expand_stars(self):
+        can_select = _OneTimeSelector(self._get_unbound_names(self.pymodule))
+        visitor = actions.ExpandStarsVisitor(
+            self.pycore, self._current_folder(), can_select)
+        for import_statement in self.imports:
+            import_statement.accept(visitor)
+
+    def remove_duplicates(self):
+        added_imports = []
+        for import_stmt in self.imports:
+            visitor = actions.AddingVisitor(self.pycore,
+                                            [import_stmt.import_info])
+            for added_import in added_imports:
+                if added_import.accept(visitor):
+                    import_stmt.empty_import()
+            else:
+                added_imports.append(import_stmt)
+
+    def get_relative_to_absolute_list(self):
+        visitor = rope.refactor.importutils.actions.RelativeToAbsoluteVisitor(
+            self.pycore, self._current_folder())
+        for import_stmt in self.imports:
+            if not import_stmt.readonly:
+                import_stmt.accept(visitor)
+        return visitor.to_be_absolute
+
+    def get_self_import_fix_and_rename_list(self):
+        visitor = rope.refactor.importutils.actions.SelfImportVisitor(
+            self.pycore, self._current_folder(), self.pymodule.get_resource())
+        for import_stmt in self.imports:
+            if not import_stmt.readonly:
+                import_stmt.accept(visitor)
+        return visitor.to_be_fixed, visitor.to_be_renamed
+
+    def _current_folder(self):
+        return self.pymodule.get_resource().parent
+
+    def sort_imports(self):
+        # IDEA: Sort from import list
+        visitor = actions.SortingVisitor(self.pycore, self._current_folder())
+        for import_statement in self.imports:
+            import_statement.accept(visitor)
+        in_projects = sorted(visitor.in_project, self._compare_imports)
+        third_party = sorted(visitor.third_party, self._compare_imports)
+        standards = sorted(visitor.standard, self._compare_imports)
+        future = sorted(visitor.future, self._compare_imports)
+        blank_lines = 0
+        last_index = self._first_import_line()
+        last_index = self._move_imports(future, last_index, 0)
+        last_index = self._move_imports(standards, last_index, 1)
+        last_index = self._move_imports(third_party, last_index, 1)
+        last_index = self._move_imports(in_projects, last_index, 1)
+        self.separating_lines = 2
+
+    def _first_import_line(self):
+        nodes = self.pymodule.get_ast().body
+        lineno = 0
+        if self.pymodule.get_doc() is not None:
+            lineno = 1
+        if len(nodes) > lineno:
+            lineno = self.pymodule.logical_lines.logical_line_in(
+                nodes[lineno].lineno)[0]
+        else:
+            lineno = self.pymodule.lines.length()
+        while lineno > 1:
+            line = self.pymodule.lines.get_line(lineno - 1)
+            if line.strip() == '':
+                lineno -= 1
+            else:
+                break
+        return lineno
+
+    def _compare_imports(self, stmt1, stmt2):
+        str1 = stmt1.get_import_statement()
+        str2 = stmt2.get_import_statement()
+        if str1.startswith('from ') and not str2.startswith('from '):
+            return 1
+        if not str1.startswith('from ') and str2.startswith('from '):
+            return -1
+        return cmp(str1, str2)
+
+    def _move_imports(self, imports, index, blank_lines):
+        if imports:
+            imports[0].move(index, blank_lines)
+            index += 1
+            if len(imports) > 1:
+                for stmt in imports[1:]:
+                    stmt.move(index)
+                    index += 1
+        return index
+
+    def handle_long_imports(self, maxdots, maxlength):
+        visitor = actions.LongImportVisitor(
+            self._current_folder(), self.pycore, maxdots, maxlength)
+        for import_statement in self.imports:
+            if not import_statement.readonly:
+                import_statement.accept(visitor)
+        for import_info in visitor.new_imports:
+            self.add_import(import_info)
+        return visitor.to_be_renamed
+
+    def remove_pyname(self, pyname):
+        """Removes pyname when imported in ``from mod import x``"""
+        visitor = actions.RemovePyNameVisitor(self.pycore, self.pymodule,
+                                              pyname, self._current_folder())
+        for import_stmt in self.imports:
+            import_stmt.accept(visitor)
+
+
+class _OneTimeSelector(object):
+
+    def __init__(self, names):
+        self.names = names
+        self.selected_names = set()
+
+    def __call__(self, imported_primary):
+        if self._can_name_be_added(imported_primary):
+            for name in self._get_dotted_tokens(imported_primary):
+                self.selected_names.add(name)
+            return True
+        return False
+
+    def _get_dotted_tokens(self, imported_primary):
+        tokens = imported_primary.split('.')
+        for i in range(len(tokens)):
+            yield '.'.join(tokens[:i + 1])
+
+    def _can_name_be_added(self, imported_primary):
+        for name in self._get_dotted_tokens(imported_primary):
+            if name in self.names and name not in self.selected_names:
+                return True
+        return False
+
+
+class _UnboundNameFinder(object):
+
+    def __init__(self, pyobject):
+        self.pyobject = pyobject
+
+    def _visit_child_scope(self, node):
+        pyobject = self.pyobject.get_module().get_scope().\
+                   get_inner_scope_for_line(node.lineno).pyobject
+        visitor = _LocalUnboundNameFinder(pyobject, self)
+        for child in ast.get_child_nodes(node):
+            ast.walk(child, visitor)
+
+    def _FunctionDef(self, node):
+        self._visit_child_scope(node)
+
+    def _ClassDef(self, node):
+        self._visit_child_scope(node)
+
+    def _Name(self, node):
+        if self._get_root()._is_node_interesting(node) and \
+           not self.is_bound(node.id):
+            self.add_unbound(node.id)
+
+    def _Attribute(self, node):
+        result = []
+        while isinstance(node, ast.Attribute):
+            result.append(node.attr)
+            node = node.value
+        if isinstance(node, ast.Name):
+            result.append(node.id)
+            primary = '.'.join(reversed(result))
+            if self._get_root()._is_node_interesting(node) and \
+               not self.is_bound(primary):
+                self.add_unbound(primary)
+        else:
+            ast.walk(node, self)
+
+    def _get_root(self):
+        pass
+
+    def is_bound(self, name, propagated=False):
+        pass
+
+    def add_unbound(self, name):
+        pass
+
+
+class _GlobalUnboundNameFinder(_UnboundNameFinder):
+
+    def __init__(self, pymodule, wanted_pyobject):
+        super(_GlobalUnboundNameFinder, self).__init__(pymodule)
+        self.unbound = set()
+        self.names = set()
+        for name, pyname in pymodule._get_structural_attributes().items():
+            if not isinstance(pyname, (rope.base.pynames.ImportedName,
+                                       rope.base.pynames.ImportedModule)):
+                self.names.add(name)
+        wanted_scope = wanted_pyobject.get_scope()
+        self.start = wanted_scope.get_start()
+        self.end = wanted_scope.get_end() + 1
+
+    def _get_root(self):
+        return self
+
+    def is_bound(self, primary, propagated=False):
+        name = primary.split('.')[0]
+        if name in self.names:
+            return True
+        return False
+
+    def add_unbound(self, name):
+        names = name.split('.')
+        for i in range(len(names)):
+            self.unbound.add('.'.join(names[:i + 1]))
+
+    def _is_node_interesting(self, node):
+        return self.start <= node.lineno < self.end
+
+
+class _LocalUnboundNameFinder(_UnboundNameFinder):
+
+    def __init__(self, pyobject, parent):
+        super(_LocalUnboundNameFinder, self).__init__(pyobject)
+        self.parent = parent
+
+    def _get_root(self):
+        return self.parent._get_root()
+
+    def is_bound(self, primary, propagated=False):
+        name = primary.split('.')[0]
+        if propagated:
+            names = self.pyobject.get_scope().get_propagated_names()
+        else:
+            names = self.pyobject.get_scope().get_names()
+        if name in names or self.parent.is_bound(name, propagated=True):
+            return True
+        return False
+
+    def add_unbound(self, name):
+        self.parent.add_unbound(name)
+
+
+class _GlobalImportFinder(object):
+
+    def __init__(self, pymodule, pycore):
+        self.current_folder = None
+        if pymodule.get_resource():
+            self.current_folder = pymodule.get_resource().parent
+            self.pymodule = pymodule
+        self.pycore = pycore
+        self.imports = []
+        self.pymodule = pymodule
+        self.lines = self.pymodule.lines
+
+    def visit_import(self, node, end_line):
+        start_line = node.lineno
+        import_statement = importinfo.ImportStatement(
+            importinfo.NormalImport(self._get_names(node.names)),
+            start_line, end_line, self._get_text(start_line, end_line),
+            blank_lines=self._count_empty_lines_before(start_line))
+        self.imports.append(import_statement)
+
+    def _count_empty_lines_before(self, lineno):
+        result = 0
+        for current in range(lineno - 1, 0, -1):
+            line = self.lines.get_line(current)
+            if line.strip() == '':
+                result += 1
+            else:
+                break
+        return result
+
+    def _count_empty_lines_after(self, lineno):
+        result = 0
+        for current in range(lineno + 1, self.lines.length()):
+            line = self.lines.get_line(current)
+            if line.strip() == '':
+                result += 1
+            else:
+                break
+        return result
+
+    def get_separating_line_count(self):
+        if not self.imports:
+            return 0
+        return self._count_empty_lines_after(self.imports[-1].end_line - 1)
+
+    def _get_text(self, start_line, end_line):
+        result = []
+        for index in range(start_line, end_line):
+            result.append(self.lines.get_line(index))
+        return '\n'.join(result)
+
+    def visit_from(self, node, end_line):
+        level = 0
+        if node.level:
+            level = node.level
+        import_info = importinfo.FromImport(
+            node.module, level, self._get_names(node.names))
+        start_line = node.lineno
+        self.imports.append(importinfo.ImportStatement(
+                            import_info, node.lineno, end_line,
+                            self._get_text(start_line, end_line),
+                            blank_lines=self._count_empty_lines_before(start_line)))
+
+    def _get_names(self, alias_names):
+        result = []
+        for alias in alias_names:
+            result.append((alias.name, alias.asname))
+        return result
+
+    def find_import_statements(self):
+        nodes = self.pymodule.get_ast().body
+        for index, node in enumerate(nodes):
+            if isinstance(node, (ast.Import, ast.ImportFrom)):
+                lines = self.pymodule.logical_lines
+                end_line = lines.logical_line_in(node.lineno)[1] + 1
+            if isinstance(node, ast.Import):
+                self.visit_import(node, end_line)
+            if isinstance(node, ast.ImportFrom):
+                self.visit_from(node, end_line)
+        return self.imports
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/inline.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,615 @@
+# Known Bugs when inlining a function/method
+# The values passed to function are inlined using _inlined_variable.
+# This may cause two problems, illustrated in the examples below
+#
+# def foo(var1):
+#    var1 = var1*10
+#    return var1
+#
+#  If a call to foo(20) is inlined, the result of inlined function is 20,
+#  but it should be 200.
+#
+# def foo(var1):
+#    var2 = var1*10
+#    return var2
+#
+# 2- If a call to foo(10+10) is inlined the result of inlined function is 110
+#  but it should be 200.
+
+import re
+
+import rope.base.exceptions
+import rope.refactor.functionutils
+from rope.base import (pynames, pyobjects, codeanalyze,
+                       taskhandle, evaluate, worder, utils)
+from rope.base.change import ChangeSet, ChangeContents
+from rope.refactor import (occurrences, rename, sourceutils,
+                           importutils, move, change_signature)
+
+def unique_prefix():
+    n = 0
+    while True:
+        yield "__" + str(n) + "__"
+        n += 1
+
+def create_inline(project, resource, offset):
+    """Create a refactoring object for inlining
+
+    Based on `resource` and `offset` it returns an instance of
+    `InlineMethod`, `InlineVariable` or `InlineParameter`.
+
+    """
+    pycore = project.pycore
+    pyname = _get_pyname(pycore, resource, offset)
+    message = 'Inline refactoring should be performed on ' \
+              'a method, local variable or parameter.'
+    if pyname is None:
+        raise rope.base.exceptions.RefactoringError(message)
+    if isinstance(pyname, pynames.ImportedName):
+        pyname = pyname._get_imported_pyname()
+    if isinstance(pyname, pynames.AssignedName):
+        return InlineVariable(project, resource, offset)
+    if isinstance(pyname, pynames.ParameterName):
+        return InlineParameter(project, resource, offset)
+    if isinstance(pyname.get_object(), pyobjects.PyFunction):
+        return InlineMethod(project, resource, offset)
+    else:
+        raise rope.base.exceptions.RefactoringError(message)
+
+
+class _Inliner(object):
+
+    def __init__(self, project, resource, offset):
+        self.project = project
+        self.pycore = project.pycore
+        self.pyname = _get_pyname(self.pycore, resource, offset)
+        range_finder = worder.Worder(resource.read())
+        self.region = range_finder.get_primary_range(offset)
+        self.name = range_finder.get_word_at(offset)
+        self.offset = offset
+        self.original = resource
+
+    def get_changes(self, *args, **kwds):
+        pass
+
+    def get_kind(self):
+        """Return either 'variable', 'method' or 'parameter'"""
+
+
+class InlineMethod(_Inliner):
+
+    def __init__(self, *args, **kwds):
+        super(InlineMethod, self).__init__(*args, **kwds)
+        self.pyfunction = self.pyname.get_object()
+        self.pymodule = self.pyfunction.get_module()
+        self.resource = self.pyfunction.get_module().get_resource()
+        self.occurrence_finder = occurrences.create_finder(
+            self.pycore, self.name, self.pyname)
+        self.normal_generator = _DefinitionGenerator(self.project,
+                                                     self.pyfunction)
+        self._init_imports()
+
+    def _init_imports(self):
+        body = sourceutils.get_body(self.pyfunction)
+        body, imports = move.moving_code_with_imports(
+            self.pycore, self.resource, body)
+        self.imports = imports
+        self.others_generator = _DefinitionGenerator(
+            self.project, self.pyfunction, body=body)
+
+    def _get_scope_range(self):
+        scope = self.pyfunction.get_scope()
+        lines = self.pymodule.lines
+        logicals = self.pymodule.logical_lines
+        start_line = scope.get_start()
+        if self.pyfunction.decorators:
+            decorators = self.pyfunction.decorators
+            if hasattr(decorators[0], 'lineno'):
+                start_line = decorators[0].lineno
+        start_offset = lines.get_line_start(start_line)
+        end_offset = min(lines.get_line_end(scope.end) + 1,
+                         len(self.pymodule.source_code))
+        return (start_offset, end_offset)
+
+    def get_changes(self, remove=True, only_current=False, resources=None,
+                    task_handle=taskhandle.NullTaskHandle()):
+        """Get the changes this refactoring makes
+
+        If `remove` is `False` the definition will not be removed.  If
+        `only_current` is `True`, the the current occurrence will be
+        inlined, only.
+        """
+        changes = ChangeSet('Inline method <%s>' % self.name)
+        if resources is None:
+            resources = self.pycore.get_python_files()
+        if only_current:
+            resources = [self.original]
+            if remove:
+                resources.append(self.resource)
+        job_set = task_handle.create_jobset('Collecting Changes',
+                                            len(resources))
+        for file in resources:
+            job_set.started_job(file.path)
+            if file == self.resource:
+                changes.add_change(self._defining_file_changes(
+                        changes, remove=remove, only_current=only_current))
+            else:
+                aim = None
+                if only_current and self.original == file:
+                    aim = self.offset
+                handle = _InlineFunctionCallsForModuleHandle(
+                    self.pycore, file, self.others_generator, aim)
+                result = move.ModuleSkipRenamer(
+                    self.occurrence_finder, file, handle).get_changed_module()
+                if result is not None:
+                    result = _add_imports(self.pycore, result,
+                                          file, self.imports)
+                    if remove:
+                        result = _remove_from(self.pycore, self.pyname,
+                                              result, file)
+                    changes.add_change(ChangeContents(file, result))
+            job_set.finished_job()
+        return changes
+
+    def _get_removed_range(self):
+        scope = self.pyfunction.get_scope()
+        lines = self.pymodule.lines
+        logical = self.pymodule.logical_lines
+        start_line = scope.get_start()
+        start, end = self._get_scope_range()
+        end_line = scope.get_end()
+        for i in range(end_line + 1, lines.length()):
+            if lines.get_line(i).strip() == '':
+                end_line = i
+            else:
+                break
+        end = min(lines.get_line_end(end_line) + 1,
+                  len(self.pymodule.source_code))
+        return (start, end)
+
+    def _defining_file_changes(self, changes, remove, only_current):
+        start_offset, end_offset = self._get_removed_range()
+        aim = None
+        if only_current:
+            if self.resource == self.original:
+                aim = self.offset
+            else:
+                # we don't want to change any of them
+                aim = len(self.resource.read()) + 100
+        handle = _InlineFunctionCallsForModuleHandle(
+            self.pycore, self.resource,
+            self.normal_generator, aim_offset=aim)
+        replacement = None
+        if remove:
+            replacement = self._get_method_replacement()
+        result = move.ModuleSkipRenamer(
+            self.occurrence_finder, self.resource, handle, start_offset,
+            end_offset, replacement).get_changed_module()
+        return ChangeContents(self.resource, result)
+
+    def _get_method_replacement(self):
+        if self._is_the_last_method_of_a_class():
+            indents = sourceutils.get_indents(
+                self.pymodule.lines, self.pyfunction.get_scope().get_start())
+            return ' ' * indents + 'pass\n'
+        return ''
+
+    def _is_the_last_method_of_a_class(self):
+        pyclass = self.pyfunction.parent
+        if not isinstance(pyclass, pyobjects.PyClass):
+            return False
+        class_start, class_end = sourceutils.get_body_region(pyclass)
+        source = self.pymodule.source_code
+        lines = self.pymodule.lines
+        func_start, func_end = self._get_scope_range()
+        if source[class_start:func_start].strip() == '' and \
+           source[func_end:class_end].strip() == '':
+            return True
+        return False
+
+    def get_kind(self):
+        return 'method'
+
+
+class InlineVariable(_Inliner):
+
+    def __init__(self, *args, **kwds):
+        super(InlineVariable, self).__init__(*args, **kwds)
+        self.pymodule = self.pyname.get_definition_location()[0]
+        self.resource = self.pymodule.get_resource()
+        self._check_exceptional_conditions()
+        self._init_imports()
+
+    def _check_exceptional_conditions(self):
+        if len(self.pyname.assignments) != 1:
+            raise rope.base.exceptions.RefactoringError(
+                'Local variable should be assigned once for inlining.')
+
+    def get_changes(self, remove=True, only_current=False, resources=None,
+                    task_handle=taskhandle.NullTaskHandle()):
+        if resources is None:
+            if rename._is_local(self.pyname):
+                resources = [self.resource]
+            else:
+                resources = self.pycore.get_python_files()
+        if only_current:
+            resources = [self.original]
+            if remove and self.original != self.resource:
+                resources.append(self.resource)
+        changes = ChangeSet('Inline variable <%s>' % self.name)
+        jobset = task_handle.create_jobset('Calculating changes',
+                                           len(resources))
+
+        for resource in resources:
+            jobset.started_job(resource.path)
+            if resource == self.resource:
+                source = self._change_main_module(remove, only_current)
+                changes.add_change(ChangeContents(self.resource, source))
+            else:
+                result = self._change_module(resource, remove, only_current)
+                if result is not None:
+                    result = _add_imports(self.pycore, result,
+                                          resource, self.imports)
+                    changes.add_change(ChangeContents(resource, result))
+            jobset.finished_job()
+        return changes
+
+    def _change_main_module(self, remove, only_current):
+        region = None
+        if only_current and self.original == self.resource:
+            region = self.region
+        return _inline_variable(self.pycore, self.pymodule, self.pyname,
+                                self.name, remove=remove, region=region)
+
+    def _init_imports(self):
+        vardef = _getvardef(self.pymodule, self.pyname)
+        self.imported, self.imports = move.moving_code_with_imports(
+            self.pycore, self.resource, vardef)
+
+    def _change_module(self, resource, remove, only_current):
+        filters = [occurrences.NoImportsFilter(),
+                   occurrences.PyNameFilter(self.pyname)]
+        if only_current and resource == self.original:
+            def check_aim(occurrence):
+                start, end = occurrence.get_primary_range()
+                if self.offset < start or end < self.offset:
+                    return False
+            filters.insert(0, check_aim)
+        finder = occurrences.Finder(self.pycore, self.name, filters=filters)
+        changed = rename.rename_in_module(
+            finder, self.imported, resource=resource, replace_primary=True)
+        if changed and remove:
+            changed = _remove_from(self.pycore, self.pyname, changed, resource)
+        return changed
+
+    def get_kind(self):
+        return 'variable'
+
+
+class InlineParameter(_Inliner):
+
+    def __init__(self, *args, **kwds):
+        super(InlineParameter, self).__init__(*args, **kwds)
+        resource, offset = self._function_location()
+        index = self.pyname.index
+        self.changers = [change_signature.ArgumentDefaultInliner(index)]
+        self.signature = change_signature.ChangeSignature(self.project,
+                                                          resource, offset)
+
+    def _function_location(self):
+        pymodule, lineno = self.pyname.get_definition_location()
+        resource = pymodule.get_resource()
+        start = pymodule.lines.get_line_start(lineno)
+        word_finder = worder.Worder(pymodule.source_code)
+        offset = word_finder.find_function_offset(start)
+        return resource, offset
+
+    def get_changes(self, **kwds):
+        """Get the changes needed by this refactoring
+
+        See `rope.refactor.change_signature.ChangeSignature.get_changes()`
+        for arguments.
+        """
+        return self.signature.get_changes(self.changers, **kwds)
+
+    def get_kind(self):
+        return 'parameter'
+
+
+def _join_lines(lines):
+    definition_lines = []
+    for unchanged_line in lines:
+        line = unchanged_line.strip()
+        if line.endswith('\\'):
+            line = line[:-1].strip()
+        definition_lines.append(line)
+    joined = ' '.join(definition_lines)
+    return joined
+
+
+class _DefinitionGenerator(object):
+    unique_prefix = unique_prefix()
+    def __init__(self, project, pyfunction, body=None):
+        self.pycore = project.pycore
+        self.pyfunction = pyfunction
+        self.pymodule = pyfunction.get_module()
+        self.resource = self.pymodule.get_resource()
+        self.definition_info = self._get_definition_info()
+        self.definition_params = self._get_definition_params()
+        self._calculated_definitions = {}
+        if body is not None:
+            self.body = body
+        else:
+            self.body = sourceutils.get_body(self.pyfunction)
+
+    def _get_definition_info(self):
+        return rope.refactor.functionutils.DefinitionInfo.read(self.pyfunction)
+
+    def _get_definition_params(self):
+        definition_info = self.definition_info
+        paramdict = dict([pair for pair in definition_info.args_with_defaults])
+        if definition_info.args_arg is not None or \
+           definition_info.keywords_arg is not None:
+            raise rope.base.exceptions.RefactoringError(
+                'Cannot inline functions with list and keyword arguements.')
+        if self.pyfunction.get_kind() == 'classmethod':
+            paramdict[definition_info.args_with_defaults[0][0]] = \
+                self.pyfunction.parent.get_name()
+        return paramdict
+
+    def get_function_name(self):
+        return self.pyfunction.get_name()
+
+    def get_definition(self, primary, pyname, call, host_vars=[],returns=False):
+        # caching already calculated definitions
+        return self._calculate_definition(primary, pyname, call,
+                           host_vars, returns)
+
+    def _calculate_header(self, primary, pyname, call):
+        # A header is created which initializes parameters
+        # to the values passed to the function.
+        call_info = rope.refactor.functionutils.CallInfo.read(
+            primary, pyname, self.definition_info, call)
+        paramdict = self.definition_params
+        mapping = rope.refactor.functionutils.ArgumentMapping(
+            self.definition_info, call_info)
+        for param_name, value in mapping.param_dict.items():
+            paramdict[param_name] = value
+        header = ''
+        to_be_inlined = []
+        mod = self.pycore.get_string_module(self.body)
+        all_names = mod.get_scope().get_names()
+        assigned_names = [name for name in all_names if
+            isinstance(all_names[name], rope.base.pynamesdef.AssignedName)]
+        for name, value in paramdict.items():
+            if name != value and value is not None:
+                header += name + ' = ' + value.replace('\n', ' ') + '\n'
+                to_be_inlined.append(name)
+        return header, to_be_inlined
+
+    def _calculate_definition(self, primary, pyname, call, host_vars, returns):
+
+        header, to_be_inlined = self._calculate_header(primary, pyname, call)
+
+        source = header + self.body
+        mod = self.pycore.get_string_module(source)
+        name_dict = mod.get_scope().get_names()
+        all_names =   [x for x in  name_dict if
+            not isinstance(name_dict[x], rope.base.builtins.BuiltinName)]
+
+        # If there is a name conflict, all variable names
+        # inside the inlined function are renamed
+        if len(set(all_names).intersection(set(host_vars))) > 0:
+
+            prefix = _DefinitionGenerator.unique_prefix.next()
+            guest = self.pycore.get_string_module(source, self.resource)
+
+            to_be_inlined = [prefix+item for item in to_be_inlined]
+            for item in all_names:
+                pyname = guest[item]
+                occurrence_finder = occurrences.create_finder(
+                                        self.pycore, item, pyname)
+                source = rename.rename_in_module(occurrence_finder,
+                                         prefix+item, pymodule=guest)
+                guest = self.pycore.get_string_module(source, self.resource)
+
+        #parameters not reassigned inside the functions are now inlined.
+        for name in to_be_inlined:
+            pymodule = self.pycore.get_string_module(source, self.resource)
+            pyname = pymodule[name]
+            source = _inline_variable(self.pycore, pymodule, pyname, name)
+
+        return self._replace_returns_with(source, returns)
+
+    def _replace_returns_with(self, source, returns):
+        result = []
+        returned = None
+        last_changed = 0
+        for match in _DefinitionGenerator._get_return_pattern().finditer(source):
+            for key, value in match.groupdict().items():
+                if value and key == 'return':
+                    result.append(source[last_changed:match.start('return')])
+                    if returns:
+                        self._check_nothing_after_return(source,
+                                                         match.end('return'))
+                        returned = _join_lines(
+                            source[match.end('return'): len(source)].splitlines())
+                        last_changed = len(source)
+                    else:
+                        current = match.end('return')
+                        while current < len(source) and source[current] in ' \t':
+                            current += 1
+                        last_changed = current
+                        if current == len(source) or source[current] == '\n':
+                            result.append('pass')
+        result.append(source[last_changed:])
+        return ''.join(result), returned
+
+    def _check_nothing_after_return(self, source, offset):
+        lines = codeanalyze.SourceLinesAdapter(source)
+        lineno = lines.get_line_number(offset)
+        logical_lines = codeanalyze.LogicalLineFinder(lines)
+        lineno = logical_lines.logical_line_in(lineno)[1]
+        if source[lines.get_line_end(lineno):len(source)].strip() != '':
+            raise rope.base.exceptions.RefactoringError(
+                'Cannot inline functions with statements after return statement.')
+
+    @classmethod
+    def _get_return_pattern(cls):
+        if not hasattr(cls, '_return_pattern'):
+            def named_pattern(name, list_):
+                return "(?P<%s>" % name + "|".join(list_) + ")"
+            comment_pattern = named_pattern('comment', [r'#[^\n]*'])
+            string_pattern = named_pattern('string',
+                                           [codeanalyze.get_string_pattern()])
+            return_pattern = r'\b(?P<return>return)\b'
+            cls._return_pattern = re.compile(comment_pattern + "|" +
+                                             string_pattern + "|" +
+                                             return_pattern)
+        return cls._return_pattern
+
+
+class _InlineFunctionCallsForModuleHandle(object):
+
+    def __init__(self, pycore, resource,
+                 definition_generator, aim_offset=None):
+        """Inlines occurrences
+
+        If `aim` is not `None` only the occurrences that intersect
+        `aim` offset will be inlined.
+
+        """
+        self.pycore = pycore
+        self.generator = definition_generator
+        self.resource = resource
+        self.aim = aim_offset
+
+    def occurred_inside_skip(self, change_collector, occurrence):
+        if not occurrence.is_defined():
+            raise rope.base.exceptions.RefactoringError(
+                'Cannot inline functions that reference themselves')
+
+    def occurred_outside_skip(self, change_collector, occurrence):
+        start, end = occurrence.get_primary_range()
+        # we remove out of date imports later
+        if occurrence.is_in_import_statement():
+            return
+        # the function is referenced outside an import statement
+        if not occurrence.is_called():
+            raise rope.base.exceptions.RefactoringError(
+                'Reference to inlining function other than function call'
+                ' in <file: %s, offset: %d>' % (self.resource.path, start))
+        if self.aim is not None and (self.aim < start or self.aim > end):
+            return
+        end_parens = self._find_end_parens(self.source, end - 1)
+        lineno = self.lines.get_line_number(start)
+        start_line, end_line = self.pymodule.logical_lines.\
+                               logical_line_in(lineno)
+        line_start = self.lines.get_line_start(start_line)
+        line_end = self.lines.get_line_end(end_line)
+
+
+        returns = self.source[line_start:start].strip() != '' or \
+                  self.source[end_parens:line_end].strip() != ''
+        indents = sourceutils.get_indents(self.lines, start_line)
+        primary, pyname = occurrence.get_primary_and_pyname()
+
+        host = self.pycore.resource_to_pyobject(self.resource)
+        scope = host.scope.get_inner_scope_for_line(lineno)
+        definition, returned = self.generator.get_definition(
+            primary, pyname, self.source[start:end_parens], scope.get_names(), returns=returns)
+
+        end = min(line_end + 1, len(self.source))
+        change_collector.add_change(line_start, end,
+               sourceutils.fix_indentation(definition, indents))
+        if returns:
+            name = returned
+            if name is None:
+                name = 'None'
+            change_collector.add_change(
+                line_end, end, self.source[line_start:start] + name +
+                self.source[end_parens:end])
+
+    def _find_end_parens(self, source, offset):
+        finder = worder.Worder(source)
+        return finder.get_word_parens_range(offset)[1]
+
+    @property
+    @utils.saveit
+    def pymodule(self):
+        return self.pycore.resource_to_pyobject(self.resource)
+
+    @property
+    @utils.saveit
+    def source(self):
+        if self.resource is not None:
+            return self.resource.read()
+        else:
+            return self.pymodule.source_code
+
+    @property
+    @utils.saveit
+    def lines(self):
+        return self.pymodule.lines
+
+
+def _inline_variable(pycore, pymodule, pyname, name,
+                     remove=True, region=None):
+    definition = _getvardef(pymodule, pyname)
+    start, end = _assigned_lineno(pymodule, pyname)
+
+    occurrence_finder = occurrences.create_finder(pycore, name, pyname)
+    changed_source = rename.rename_in_module(
+        occurrence_finder, definition, pymodule=pymodule,
+        replace_primary=True, writes=False, region=region)
+    if changed_source is None:
+        changed_source = pymodule.source_code
+    if remove:
+        lines = codeanalyze.SourceLinesAdapter(changed_source)
+        source = changed_source[:lines.get_line_start(start)] + \
+                 changed_source[lines.get_line_end(end) + 1:]
+    else:
+        source = changed_source
+    return source
+
+def _getvardef(pymodule, pyname):
+    assignment = pyname.assignments[0]
+    lines = pymodule.lines
+    start, end = _assigned_lineno(pymodule, pyname)
+    definition_with_assignment = _join_lines(
+        [lines.get_line(n) for n in range(start, end + 1)])
+    if assignment.levels:
+        raise rope.base.exceptions.RefactoringError(
+            'Cannot inline tuple assignments.')
+    definition = definition_with_assignment[definition_with_assignment.\
+                                            index('=') + 1:].strip()
+    return definition
+
+def _assigned_lineno(pymodule, pyname):
+    definition_line = pyname.assignments[0].ast_node.lineno
+    return pymodule.logical_lines.logical_line_in(definition_line)
+
+def _add_imports(pycore, source, resource, imports):
+    if not imports:
+        return source
+    pymodule = pycore.get_string_module(source, resource)
+    module_import = importutils.get_module_imports(pycore, pymodule)
+    for import_info in imports:
+        module_import.add_import(import_info)
+    source = module_import.get_changed_source()
+    pymodule = pycore.get_string_module(source, resource)
+    import_tools = importutils.ImportTools(pycore)
+    return import_tools.organize_imports(pymodule, unused=False, sort=False)
+
+def _get_pyname(pycore, resource, offset):
+    pymodule = pycore.resource_to_pyobject(resource)
+    pyname = evaluate.eval_location(pymodule, offset)
+    if isinstance(pyname, pynames.ImportedName):
+        pyname = pyname._get_imported_pyname()
+    return pyname
+
+def _remove_from(pycore, pyname, source, resource):
+    pymodule = pycore.get_string_module(source, resource)
+    module_import = importutils.get_module_imports(pycore, pymodule)
+    module_import.remove_pyname(pyname)
+    return module_import.get_changed_source()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/introduce_factory.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,133 @@
+import rope.base.exceptions
+import rope.base.pyobjects
+from rope.base import taskhandle, evaluate
+from rope.base.change import (ChangeSet, ChangeContents)
+from rope.refactor import rename, occurrences, sourceutils, importutils
+
+
+class IntroduceFactory(object):
+
+    def __init__(self, project, resource, offset):
+        self.pycore = project.pycore
+        self.offset = offset
+
+        this_pymodule = self.pycore.resource_to_pyobject(resource)
+        self.old_pyname = evaluate.eval_location(this_pymodule, offset)
+        if self.old_pyname is None or not isinstance(self.old_pyname.get_object(),
+                                                     rope.base.pyobjects.PyClass):
+            raise rope.base.exceptions.RefactoringError(
+                'Introduce factory should be performed on a class.')
+        self.old_name = self.old_pyname.get_object().get_name()
+        self.pymodule = self.old_pyname.get_object().get_module()
+        self.resource = self.pymodule.get_resource()
+
+    def get_changes(self, factory_name, global_factory=False, resources=None,
+                    task_handle=taskhandle.NullTaskHandle()):
+        """Get the changes this refactoring makes
+
+        `factory_name` indicates the name of the factory function to
+        be added.  If `global_factory` is `True` the factory will be
+        global otherwise a static method is added to the class.
+
+        `resources` can be a list of `rope.base.resource.File`\s that
+        this refactoring should be applied on; if `None` all python
+        files in the project are searched.
+
+        """
+        if resources is None:
+            resources = self.pycore.get_python_files()
+        changes = ChangeSet('Introduce factory method <%s>' % factory_name)
+        job_set = task_handle.create_jobset('Collecting Changes',
+                                            len(resources))
+        self._change_module(resources, changes, factory_name,
+                            global_factory, job_set)
+        return changes
+
+    def get_name(self):
+        """Return the name of the class"""
+        return self.old_name
+
+    def _change_module(self, resources, changes,
+                       factory_name, global_, job_set):
+        if global_:
+            replacement = '__rope_factory_%s_' % factory_name
+        else:
+            replacement = self._new_function_name(factory_name, global_)
+
+        for file_ in resources:
+            job_set.started_job(file_.path)
+            if file_ == self.resource:
+                self._change_resource(changes, factory_name, global_)
+                job_set.finished_job()
+                continue
+            changed_code = self._rename_occurrences(file_, replacement,
+                                                    global_)
+            if changed_code is not None:
+                if global_:
+                    new_pymodule = self.pycore.get_string_module(changed_code,
+                                                                 self.resource)
+                    modname = self.pycore.modname(self.resource)
+                    changed_code, imported = importutils.add_import(
+                        self.pycore, new_pymodule, modname, factory_name)
+                    changed_code = changed_code.replace(replacement, imported)
+                changes.add_change(ChangeContents(file_, changed_code))
+            job_set.finished_job()
+
+    def _change_resource(self, changes, factory_name, global_):
+        class_scope = self.old_pyname.get_object().get_scope()
+        source_code = self._rename_occurrences(
+            self.resource, self._new_function_name(factory_name,
+                                                   global_), global_)
+        if source_code is None:
+            source_code = self.pymodule.source_code
+        else:
+            self.pymodule = self.pycore.get_string_module(
+                source_code, resource=self.resource)
+        lines = self.pymodule.lines
+        start = self._get_insertion_offset(class_scope, lines)
+        result = source_code[:start]
+        result += self._get_factory_method(lines, class_scope,
+                                           factory_name, global_)
+        result += source_code[start:]
+        changes.add_change(ChangeContents(self.resource, result))
+
+    def _get_insertion_offset(self, class_scope, lines):
+        start_line = class_scope.get_end()
+        if class_scope.get_scopes():
+            start_line = class_scope.get_scopes()[-1].get_end()
+        start = lines.get_line_end(start_line) + 1
+        return start
+
+    def _get_factory_method(self, lines, class_scope,
+                            factory_name, global_):
+        unit_indents = ' ' * sourceutils.get_indent(self.pycore)
+        if global_:
+            if self._get_scope_indents(lines, class_scope) > 0:
+                raise rope.base.exceptions.RefactoringError(
+                    'Cannot make global factory method for nested classes.')
+            return ('\ndef %s(*args, **kwds):\n%sreturn %s(*args, **kwds)\n' %
+                    (factory_name, unit_indents, self.old_name))
+        unindented_factory = \
+            ('@staticmethod\ndef %s(*args, **kwds):\n' % factory_name +
+             '%sreturn %s(*args, **kwds)\n' % (unit_indents, self.old_name))
+        indents = self._get_scope_indents(lines, class_scope) + \
+                  sourceutils.get_indent(self.pycore)
+        return '\n' + sourceutils.indent_lines(unindented_factory, indents)
+
+    def _get_scope_indents(self, lines, scope):
+        return sourceutils.get_indents(lines, scope.get_start())
+
+    def _new_function_name(self, factory_name, global_):
+        if global_:
+            return factory_name
+        else:
+            return self.old_name + '.' + factory_name
+
+    def _rename_occurrences(self, file_, changed_name, global_factory):
+        finder = occurrences.create_finder(self.pycore, self.old_name,
+                                           self.old_pyname, only_calls=True)
+        result = rename.rename_in_module(finder, changed_name, resource=file_,
+                                         replace_primary=global_factory)
+        return result
+
+IntroduceFactoryRefactoring = IntroduceFactory
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/introduce_parameter.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,95 @@
+import rope.base.change
+from rope.base import exceptions, evaluate, worder, codeanalyze
+from rope.refactor import functionutils, sourceutils, occurrences
+
+
+class IntroduceParameter(object):
+    """Introduce parameter refactoring
+
+    This refactoring adds a new parameter to a function and replaces
+    references to an expression in it with the new parameter.
+
+    The parameter finding part is different from finding similar
+    pieces in extract refactorings.  In this refactoring parameters
+    are found based on the object they reference to.  For instance
+    in::
+
+      class A(object):
+          var = None
+
+      class B(object):
+          a = A()
+
+      b = B()
+      a = b.a
+
+      def f(a):
+          x = b.a.var + a.var
+
+    using this refactoring on ``a.var`` with ``p`` as the new
+    parameter name, will result in::
+
+      def f(p=a.var):
+          x = p + p
+
+    """
+
+    def __init__(self, project, resource, offset):
+        self.pycore = project.pycore
+        self.resource = resource
+        self.offset = offset
+        self.pymodule = self.pycore.resource_to_pyobject(self.resource)
+        scope = self.pymodule.get_scope().get_inner_scope_for_offset(offset)
+        if scope.get_kind() != 'Function':
+            raise exceptions.RefactoringError(
+                'Introduce parameter should be performed inside functions')
+        self.pyfunction = scope.pyobject
+        self.name, self.pyname = self._get_name_and_pyname()
+        if self.pyname is None:
+            raise exceptions.RefactoringError(
+                'Cannot find the definition of <%s>' % self.name)
+
+    def _get_primary(self):
+        word_finder = worder.Worder(self.resource.read())
+        return word_finder.get_primary_at(self.offset)
+
+    def _get_name_and_pyname(self):
+        return (worder.get_name_at(self.resource, self.offset),
+                evaluate.eval_location(self.pymodule, self.offset))
+
+    def get_changes(self, new_parameter):
+        definition_info = functionutils.DefinitionInfo.read(self.pyfunction)
+        definition_info.args_with_defaults.append((new_parameter,
+                                                   self._get_primary()))
+        collector = codeanalyze.ChangeCollector(self.resource.read())
+        header_start, header_end = self._get_header_offsets()
+        body_start, body_end = sourceutils.get_body_region(self.pyfunction)
+        collector.add_change(header_start, header_end,
+                             definition_info.to_string())
+        self._change_function_occurances(collector, body_start,
+                                         body_end, new_parameter)
+        changes = rope.base.change.ChangeSet('Introduce parameter <%s>' %
+                                             new_parameter)
+        change = rope.base.change.ChangeContents(self.resource,
+                                                 collector.get_changed())
+        changes.add_change(change)
+        return changes
+
+    def _get_header_offsets(self):
+        lines = self.pymodule.lines
+        start_line = self.pyfunction.get_scope().get_start()
+        end_line = self.pymodule.logical_lines.\
+                   logical_line_in(start_line)[1]
+        start = lines.get_line_start(start_line)
+        end = lines.get_line_end(end_line)
+        start = self.pymodule.source_code.find('def', start) + 4
+        end = self.pymodule.source_code.rfind(':', start, end)
+        return start, end
+
+    def _change_function_occurances(self, collector, function_start,
+                                    function_end, new_name):
+        finder = occurrences.create_finder(self.pycore, self.name, self.pyname)
+        for occurrence in finder.find_occurrences(resource=self.resource):
+            start, end = occurrence.get_primary_range()
+            if function_start <= start < function_end:
+                collector.add_change(start, end, new_name)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/localtofield.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,50 @@
+from rope.base import pynames, evaluate, exceptions, worder
+from rope.refactor.rename import Rename
+
+
+class LocalToField(object):
+
+    def __init__(self, project, resource, offset):
+        self.project = project
+        self.pycore = project.pycore
+        self.resource = resource
+        self.offset = offset
+
+    def get_changes(self):
+        name = worder.get_name_at(self.resource, self.offset)
+        this_pymodule = self.pycore.resource_to_pyobject(self.resource)
+        pyname = evaluate.eval_location(this_pymodule, self.offset)
+        if not self._is_a_method_local(pyname):
+            raise exceptions.RefactoringError(
+                'Convert local variable to field should be performed on \n'
+                'a local variable of a method.')
+
+        pymodule, lineno = pyname.get_definition_location()
+        function_scope = pymodule.get_scope().get_inner_scope_for_line(lineno)
+        # Not checking redefinition
+        #self._check_redefinition(name, function_scope)
+
+        new_name = self._get_field_name(function_scope.pyobject, name)
+        changes = Rename(self.project, self.resource, self.offset).\
+                  get_changes(new_name, resources=[self.resource])
+        return changes
+
+    def _check_redefinition(self, name, function_scope):
+        class_scope = function_scope.parent
+        if name in class_scope.pyobject:
+            raise exceptions.RefactoringError(
+                'The field %s already exists' % name)
+
+    def _get_field_name(self, pyfunction, name):
+        self_name = pyfunction.get_param_names()[0]
+        new_name = self_name + '.' + name
+        return new_name
+
+    def _is_a_method_local(self, pyname):
+        pymodule, lineno = pyname.get_definition_location()
+        holding_scope = pymodule.get_scope().get_inner_scope_for_line(lineno)
+        parent = holding_scope.parent
+        return isinstance(pyname, pynames.AssignedName) and \
+               pyname in holding_scope.get_names().values() and \
+               holding_scope.get_kind() == 'Function' and \
+               parent is not None and parent.get_kind() == 'Class'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/method_object.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,87 @@
+import warnings
+
+from rope.base import pyobjects, exceptions, change, evaluate, codeanalyze
+from rope.refactor import sourceutils, occurrences, rename
+
+
+class MethodObject(object):
+
+    def __init__(self, project, resource, offset):
+        self.pycore = project.pycore
+        this_pymodule = self.pycore.resource_to_pyobject(resource)
+        pyname = evaluate.eval_location(this_pymodule, offset)
+        if pyname is None or not isinstance(pyname.get_object(),
+                                            pyobjects.PyFunction):
+            raise exceptions.RefactoringError(
+                'Replace method with method object refactoring should be '
+                'performed on a function.')
+        self.pyfunction = pyname.get_object()
+        self.pymodule = self.pyfunction.get_module()
+        self.resource = self.pymodule.get_resource()
+
+    def get_new_class(self, name):
+        body = sourceutils.fix_indentation(
+            self._get_body(), sourceutils.get_indent(self.pycore) * 2)
+        return 'class %s(object):\n\n%s%sdef __call__(self):\n%s' % \
+               (name, self._get_init(),
+                ' ' * sourceutils.get_indent(self.pycore), body)
+
+    def get_changes(self, classname=None, new_class_name=None):
+        if new_class_name is not None:
+            warnings.warn(
+                'new_class_name parameter is deprecated; use classname',
+                DeprecationWarning, stacklevel=2)
+            classname = new_class_name
+        collector = codeanalyze.ChangeCollector(self.pymodule.source_code)
+        start, end = sourceutils.get_body_region(self.pyfunction)
+        indents = sourceutils.get_indents(
+            self.pymodule.lines, self.pyfunction.get_scope().get_start()) + \
+            sourceutils.get_indent(self.pycore)
+        new_contents = ' ' * indents + 'return %s(%s)()\n' % \
+                       (classname, ', '.join(self._get_parameter_names()))
+        collector.add_change(start, end, new_contents)
+        insertion = self._get_class_insertion_point()
+        collector.add_change(insertion, insertion,
+                             '\n\n' + self.get_new_class(classname))
+        changes = change.ChangeSet('Replace method with method object refactoring')
+        changes.add_change(change.ChangeContents(self.resource,
+                                                 collector.get_changed()))
+        return changes
+
+    def _get_class_insertion_point(self):
+        current = self.pyfunction
+        while current.parent != self.pymodule:
+            current = current.parent
+        end = self.pymodule.lines.get_line_end(current.get_scope().get_end())
+        return min(end + 1, len(self.pymodule.source_code))
+
+    def _get_body(self):
+        body = sourceutils.get_body(self.pyfunction)
+        for param in self._get_parameter_names():
+            body = param + ' = None\n' + body
+            pymod = self.pycore.get_string_module(body, self.resource)
+            pyname = pymod[param]
+            finder = occurrences.create_finder(self.pycore, param, pyname)
+            result = rename.rename_in_module(finder, 'self.' + param,
+                                             pymodule=pymod)
+            body = result[result.index('\n') + 1:]
+        return body
+
+    def _get_init(self):
+        params = self._get_parameter_names()
+        indents = ' ' * sourceutils.get_indent(self.pycore)
+        if not params:
+            return ''
+        header = indents + 'def __init__(self'
+        body = ''
+        for arg in params:
+            new_name = arg
+            if arg == 'self':
+                new_name = 'host'
+            header += ', %s' % new_name
+            body += indents * 2 + 'self.%s = %s\n' % (arg, new_name)
+        header += '):'
+        return '%s\n%s\n' % (header, body)
+
+    def _get_parameter_names(self):
+        return self.pyfunction.get_param_names()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/move.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,625 @@
+"""A module containing classes for move refactoring
+
+`create_move()` is a factory for creating move refactoring objects
+based on inputs.
+
+"""
+from rope.base import pyobjects, codeanalyze, exceptions, pynames, taskhandle, evaluate, worder
+from rope.base.change import ChangeSet, ChangeContents, MoveResource
+from rope.refactor import importutils, rename, occurrences, sourceutils, functionutils
+
+
+def create_move(project, resource, offset=None):
+    """A factory for creating Move objects
+
+    Based on `resource` and `offset`, return one of `MoveModule`,
+    `MoveGlobal` or `MoveMethod` for performing move refactoring.
+
+    """
+    if offset is None:
+        return MoveModule(project, resource)
+    this_pymodule = project.pycore.resource_to_pyobject(resource)
+    pyname = evaluate.eval_location(this_pymodule, offset)
+    if pyname is None:
+        raise exceptions.RefactoringError(
+            'Move only works on classes, functions, modules and methods.')
+    pyobject = pyname.get_object()
+    if isinstance(pyobject, pyobjects.PyModule) or \
+       isinstance(pyobject, pyobjects.PyPackage):
+        return MoveModule(project, pyobject.get_resource())
+    if isinstance(pyobject, pyobjects.PyFunction) and \
+       isinstance(pyobject.parent, pyobjects.PyClass):
+        return MoveMethod(project, resource, offset)
+    if isinstance(pyobject, pyobjects.PyDefinedObject) and \
+       isinstance(pyobject.parent, pyobjects.PyModule):
+        return MoveGlobal(project, resource, offset)
+    raise exceptions.RefactoringError(
+        'Move only works on global classes/functions, modules and methods.')
+
+
+class MoveMethod(object):
+    """For moving methods
+
+    It makes a new method in the destination class and changes
+    the body of the old method to call the new method.  You can
+    inline the old method to change all of its occurrences.
+
+    """
+
+    def __init__(self, project, resource, offset):
+        self.project = project
+        self.pycore = project.pycore
+        this_pymodule = self.pycore.resource_to_pyobject(resource)
+        pyname = evaluate.eval_location(this_pymodule, offset)
+        self.method_name = worder.get_name_at(resource, offset)
+        self.pyfunction = pyname.get_object()
+        if self.pyfunction.get_kind() != 'method':
+            raise exceptions.RefactoringError('Only normal methods'
+                                              ' can be moved.')
+
+    def get_changes(self, dest_attr, new_name=None, resources=None,
+                    task_handle=taskhandle.NullTaskHandle()):
+        """Return the changes needed for this refactoring
+
+        Parameters:
+
+        - `dest_attr`: the name of the destination attribute
+        - `new_name`: the name of the new method; if `None` uses
+          the old name
+        - `resources` can be a list of `rope.base.resources.File`\s to
+          apply this refactoring on.  If `None`, the restructuring
+          will be applied to all python files.
+
+        """
+        changes = ChangeSet('Moving method <%s>' % self.method_name)
+        if resources is None:
+            resources = self.pycore.get_python_files()
+        if new_name is None:
+            new_name = self.get_method_name()
+        resource1, start1, end1, new_content1 = \
+            self._get_changes_made_by_old_class(dest_attr, new_name)
+        collector1 = codeanalyze.ChangeCollector(resource1.read())
+        collector1.add_change(start1, end1, new_content1)
+
+        resource2, start2, end2, new_content2 = \
+            self._get_changes_made_by_new_class(dest_attr, new_name)
+        if resource1 == resource2:
+            collector1.add_change(start2, end2, new_content2)
+        else:
+            collector2 = codeanalyze.ChangeCollector(resource2.read())
+            collector2.add_change(start2, end2, new_content2)
+            result = collector2.get_changed()
+            import_tools = importutils.ImportTools(self.pycore)
+            new_imports = self._get_used_imports(import_tools)
+            if new_imports:
+                goal_pymodule = self.pycore.get_string_module(result,
+                                                              resource2)
+                result = _add_imports_to_module(
+                    import_tools, goal_pymodule, new_imports)
+            if resource2 in resources:
+                changes.add_change(ChangeContents(resource2, result))
+
+        if resource1 in resources:
+            changes.add_change(ChangeContents(resource1,
+                                              collector1.get_changed()))
+        return changes
+
+    def get_method_name(self):
+        return self.method_name
+
+    def _get_used_imports(self, import_tools):
+        return importutils.get_imports(self.pycore, self.pyfunction)
+
+    def _get_changes_made_by_old_class(self, dest_attr, new_name):
+        pymodule = self.pyfunction.get_module()
+        indents = self._get_scope_indents(self.pyfunction)
+        body = 'return self.%s.%s(%s)\n' % (dest_attr, new_name,
+                                            self._get_passed_arguments_string())
+        region = sourceutils.get_body_region(self.pyfunction)
+        return (pymodule.get_resource(), region[0], region[1],
+                sourceutils.fix_indentation(body, indents))
+
+    def _get_scope_indents(self, pyobject):
+        pymodule = pyobject.get_module()
+        return sourceutils.get_indents(
+            pymodule.lines, pyobject.get_scope().get_start()) + \
+            sourceutils.get_indent(self.pycore)
+
+    def _get_changes_made_by_new_class(self, dest_attr, new_name):
+        old_pyclass = self.pyfunction.parent
+        if dest_attr not in old_pyclass:
+            raise exceptions.RefactoringError(
+                'Destination attribute <%s> not found' % dest_attr)
+        pyclass = old_pyclass[dest_attr].get_object().get_type()
+        if not isinstance(pyclass, pyobjects.PyClass):
+            raise exceptions.RefactoringError(
+                'Unknown class type for attribute <%s>' % dest_attr)
+        pymodule = pyclass.get_module()
+        resource = pyclass.get_module().get_resource()
+        start, end = sourceutils.get_body_region(pyclass)
+        pre_blanks = '\n'
+        if pymodule.source_code[start:end].strip() != 'pass':
+            pre_blanks = '\n\n'
+            start = end
+        indents = self._get_scope_indents(pyclass)
+        body = pre_blanks + sourceutils.fix_indentation(
+            self.get_new_method(new_name), indents)
+        return resource, start, end, body
+
+    def get_new_method(self, name):
+        return '%s\n%s' % (
+            self._get_new_header(name),
+            sourceutils.fix_indentation(self._get_body(),
+                                        sourceutils.get_indent(self.pycore)))
+
+    def _get_unchanged_body(self):
+        return sourceutils.get_body(self.pyfunction)
+
+    def _get_body(self, host='host'):
+        self_name = self._get_self_name()
+        body = self_name + ' = None\n' + self._get_unchanged_body()
+        pymodule = self.pycore.get_string_module(body)
+        finder = occurrences.create_finder(
+            self.pycore, self_name, pymodule[self_name])
+        result = rename.rename_in_module(finder, host, pymodule=pymodule)
+        if result is None:
+            result = body
+        return result[result.index('\n') + 1:]
+
+    def _get_self_name(self):
+        return self.pyfunction.get_param_names()[0]
+
+    def _get_new_header(self, name):
+        header = 'def %s(self' % name
+        if self._is_host_used():
+            header += ', host'
+        definition_info = functionutils.DefinitionInfo.read(self.pyfunction)
+        others = definition_info.arguments_to_string(1)
+        if others:
+            header += ', ' + others
+        return header + '):'
+
+    def _get_passed_arguments_string(self):
+        result = ''
+        if self._is_host_used():
+            result = 'self'
+        definition_info = functionutils.DefinitionInfo.read(self.pyfunction)
+        others = definition_info.arguments_to_string(1)
+        if others:
+            if result:
+                result += ', '
+            result += others
+        return result
+
+    def _is_host_used(self):
+        return self._get_body('__old_self') != self._get_unchanged_body()
+
+
+class MoveGlobal(object):
+    """For moving global function and classes"""
+
+    def __init__(self, project, resource, offset):
+        self.pycore = project.pycore
+        this_pymodule = self.pycore.resource_to_pyobject(resource)
+        self.old_pyname = evaluate.eval_location(this_pymodule, offset)
+        self.old_name = self.old_pyname.get_object().get_name()
+        pymodule = self.old_pyname.get_object().get_module()
+        self.source = pymodule.get_resource()
+        self.tools = _MoveTools(self.pycore, self.source,
+                                self.old_pyname, self.old_name)
+        self.import_tools = self.tools.import_tools
+        self._check_exceptional_conditions()
+
+    def _check_exceptional_conditions(self):
+        if self.old_pyname is None or \
+           not isinstance(self.old_pyname.get_object(), pyobjects.PyDefinedObject):
+            raise exceptions.RefactoringError(
+                'Move refactoring should be performed on a class/function.')
+        moving_pyobject = self.old_pyname.get_object()
+        if not self._is_global(moving_pyobject):
+            raise exceptions.RefactoringError(
+                'Move refactoring should be performed on a global class/function.')
+
+    def _is_global(self, pyobject):
+        return pyobject.get_scope().parent == pyobject.get_module().get_scope()
+
+    def get_changes(self, dest, resources=None,
+                    task_handle=taskhandle.NullTaskHandle()):
+        if resources is None:
+            resources = self.pycore.get_python_files()
+        if dest is None or not dest.exists():
+            raise exceptions.RefactoringError(
+                'Move destination does not exist.')
+        if dest.is_folder() and dest.has_child('__init__.py'):
+            dest = dest.get_child('__init__.py')
+        if dest.is_folder():
+            raise exceptions.RefactoringError(
+                'Move destination for non-modules should not be folders.')
+        if self.source == dest:
+            raise exceptions.RefactoringError(
+                'Moving global elements to the same module.')
+        return self._calculate_changes(dest, resources, task_handle)
+
+    def _calculate_changes(self, dest, resources, task_handle):
+        changes = ChangeSet('Moving global <%s>' % self.old_name)
+        job_set = task_handle.create_jobset('Collecting Changes',
+                                            len(resources))
+        for file_ in resources:
+            job_set.started_job(file_.path)
+            if file_ == self.source:
+                changes.add_change(self._source_module_changes(dest))
+            elif file_ == dest:
+                changes.add_change(self._dest_module_changes(dest))
+            elif self.tools.occurs_in_module(resource=file_):
+                pymodule = self.pycore.resource_to_pyobject(file_)
+                # Changing occurrences
+                placeholder = '__rope_renaming_%s_' % self.old_name
+                source = self.tools.rename_in_module(placeholder,
+                                                     resource=file_)
+                should_import = source is not None
+                # Removing out of date imports
+                pymodule = self.tools.new_pymodule(pymodule, source)
+                source = self.tools.remove_old_imports(pymodule)
+                # Adding new import
+                if should_import:
+                    pymodule = self.tools.new_pymodule(pymodule, source)
+                    source, imported = importutils.add_import(
+                        self.pycore, pymodule, self._new_modname(dest), self.old_name)
+                    source = source.replace(placeholder, imported)
+                source = self.tools.new_source(pymodule, source)
+                if source != file_.read():
+                    changes.add_change(ChangeContents(file_, source))
+            job_set.finished_job()
+        return changes
+
+    def _source_module_changes(self, dest):
+        placeholder = '__rope_moving_%s_' % self.old_name
+        handle = _ChangeMoveOccurrencesHandle(placeholder)
+        occurrence_finder = occurrences.create_finder(
+            self.pycore, self.old_name, self.old_pyname)
+        start, end = self._get_moving_region()
+        renamer = ModuleSkipRenamer(occurrence_finder, self.source,
+                                    handle, start, end)
+        source = renamer.get_changed_module()
+        if handle.occurred:
+            pymodule = self.pycore.get_string_module(source, self.source)
+            # Adding new import
+            source, imported = importutils.add_import(
+                self.pycore, pymodule, self._new_modname(dest), self.old_name)
+            source = source.replace(placeholder, imported)
+        return ChangeContents(self.source, source)
+
+    def _new_modname(self, dest):
+        return self.pycore.modname(dest)
+
+    def _dest_module_changes(self, dest):
+        # Changing occurrences
+        pymodule = self.pycore.resource_to_pyobject(dest)
+        source = self.tools.rename_in_module(self.old_name, pymodule)
+        pymodule = self.tools.new_pymodule(pymodule, source)
+
+        moving, imports = self._get_moving_element_with_imports()
+        source = self.tools.remove_old_imports(pymodule)
+        pymodule = self.tools.new_pymodule(pymodule, source)
+        pymodule, has_changed = self._add_imports2(pymodule, imports)
+
+        module_with_imports = self.import_tools.module_imports(pymodule)
+        source = pymodule.source_code
+        if module_with_imports.imports:
+            start = pymodule.lines.get_line_end(
+                module_with_imports.imports[-1].end_line - 1)
+            result = source[:start + 1] + '\n\n'
+        else:
+            result = ''
+            start = -1
+        result += moving + source[start + 1:]
+
+        # Organizing imports
+        source = result
+        pymodule = self.pycore.get_string_module(source, dest)
+        source = self.import_tools.organize_imports(pymodule, sort=False,
+                                                    unused=False)
+        return ChangeContents(dest, source)
+
+    def _get_moving_element_with_imports(self):
+        return moving_code_with_imports(
+            self.pycore, self.source, self._get_moving_element())
+
+    def _get_module_with_imports(self, source_code, resource):
+        pymodule = self.pycore.get_string_module(source_code, resource)
+        return self.import_tools.module_imports(pymodule)
+
+    def _get_moving_element(self):
+        start, end = self._get_moving_region()
+        moving = self.source.read()[start:end]
+        return moving.rstrip() + '\n'
+
+    def _get_moving_region(self):
+        pymodule = self.pycore.resource_to_pyobject(self.source)
+        lines = pymodule.lines
+        scope = self.old_pyname.get_object().get_scope()
+        start = lines.get_line_start(scope.get_start())
+        end_line = scope.get_end()
+        while end_line < lines.length() and \
+              lines.get_line(end_line + 1).strip() == '':
+            end_line += 1
+        end = min(lines.get_line_end(end_line) + 1, len(pymodule.source_code))
+        return start, end
+
+    def _add_imports2(self, pymodule, new_imports):
+        source = self.tools.add_imports(pymodule, new_imports)
+        if source is None:
+            return pymodule, False
+        else:
+            resource = pymodule.get_resource()
+            pymodule = self.pycore.get_string_module(source, resource)
+            return pymodule, True
+
+
+class MoveModule(object):
+    """For moving modules and packages"""
+
+    def __init__(self, project, resource):
+        self.project = project
+        self.pycore = project.pycore
+        if not resource.is_folder() and resource.name == '__init__.py':
+            resource = resource.parent
+        if resource.is_folder() and not resource.has_child('__init__.py'):
+            raise exceptions.RefactoringError(
+                'Cannot move non-package folder.')
+        dummy_pymodule = self.pycore.get_string_module('')
+        self.old_pyname = pynames.ImportedModule(dummy_pymodule,
+                                                 resource=resource)
+        self.source = self.old_pyname.get_object().get_resource()
+        if self.source.is_folder():
+            self.old_name = self.source.name
+        else:
+            self.old_name = self.source.name[:-3]
+        self.tools = _MoveTools(self.pycore, self.source,
+                                self.old_pyname, self.old_name)
+        self.import_tools = self.tools.import_tools
+
+    def get_changes(self, dest, resources=None,
+                    task_handle=taskhandle.NullTaskHandle()):
+        moving_pyobject = self.old_pyname.get_object()
+        if resources is None:
+            resources = self.pycore.get_python_files()
+        if dest is None or not dest.is_folder():
+            raise exceptions.RefactoringError(
+                'Move destination for modules should be packages.')
+        return self._calculate_changes(dest, resources, task_handle)
+
+    def _calculate_changes(self, dest, resources, task_handle):
+        changes = ChangeSet('Moving module <%s>' % self.old_name)
+        job_set = task_handle.create_jobset('Collecting changes',
+                                            len(resources))
+        for module in resources:
+            job_set.started_job(module.path)
+            if module == self.source:
+                self._change_moving_module(changes, dest)
+            else:
+                source = self._change_occurrences_in_module(dest,
+                                                            resource=module)
+                if source is not None:
+                    changes.add_change(ChangeContents(module, source))
+            job_set.finished_job()
+        if self.project == self.source.project:
+            changes.add_change(MoveResource(self.source, dest.path))
+        return changes
+
+    def _new_modname(self, dest):
+        destname = self.pycore.modname(dest)
+        if destname:
+            return destname + '.' + self.old_name
+        return self.old_name
+
+    def _new_import(self, dest):
+        return importutils.NormalImport([(self._new_modname(dest), None)])
+
+    def _change_moving_module(self, changes, dest):
+        if not self.source.is_folder():
+            pymodule = self.pycore.resource_to_pyobject(self.source)
+            source = self.import_tools.relatives_to_absolutes(pymodule)
+            pymodule = self.tools.new_pymodule(pymodule, source)
+            source = self._change_occurrences_in_module(dest, pymodule)
+            source = self.tools.new_source(pymodule, source)
+            if source != self.source.read():
+                changes.add_change(ChangeContents(self.source, source))
+
+    def _change_occurrences_in_module(self, dest, pymodule=None,
+                                      resource=None):
+        if not self.tools.occurs_in_module(pymodule=pymodule,
+                                           resource=resource):
+            return
+        if pymodule is None:
+            pymodule = self.pycore.resource_to_pyobject(resource)
+        new_name = self._new_modname(dest)
+        new_import = self._new_import(dest)
+        source = self.tools.rename_in_module(
+            new_name, imports=True, pymodule=pymodule, resource=resource)
+        should_import = self.tools.occurs_in_module(
+            pymodule=pymodule, resource=resource, imports=False)
+        pymodule = self.tools.new_pymodule(pymodule, source)
+        source = self.tools.remove_old_imports(pymodule)
+        if should_import:
+            pymodule = self.tools.new_pymodule(pymodule, source)
+            source = self.tools.add_imports(pymodule, [new_import])
+        source = self.tools.new_source(pymodule, source)
+        if source != pymodule.resource.read():
+            return source
+
+
+class _ChangeMoveOccurrencesHandle(object):
+
+    def __init__(self, new_name):
+        self.new_name = new_name
+        self.occurred = False
+
+    def occurred_inside_skip(self, change_collector, occurrence):
+        pass
+
+    def occurred_outside_skip(self, change_collector, occurrence):
+        start, end = occurrence.get_primary_range()
+        change_collector.add_change(start, end, self.new_name)
+        self.occurred = True
+
+
+class _MoveTools(object):
+
+    def __init__(self, pycore, source, pyname, old_name):
+        self.pycore = pycore
+        self.source = source
+        self.old_pyname = pyname
+        self.old_name = old_name
+        self.import_tools = importutils.ImportTools(self.pycore)
+
+    def remove_old_imports(self, pymodule):
+        old_source = pymodule.source_code
+        module_with_imports = self.import_tools.module_imports(pymodule)
+        class CanSelect(object):
+            changed = False
+            old_name = self.old_name
+            old_pyname = self.old_pyname
+            def __call__(self, name):
+                try:
+                    if name == self.old_name and \
+                       pymodule[name].get_object() == \
+                       self.old_pyname.get_object():
+                        self.changed = True
+                        return False
+                except exceptions.AttributeNotFoundError:
+                    pass
+                return True
+        can_select = CanSelect()
+        module_with_imports.filter_names(can_select)
+        new_source = module_with_imports.get_changed_source()
+        if old_source != new_source:
+            return new_source
+
+    def rename_in_module(self, new_name, pymodule=None,
+                          imports=False, resource=None):
+        occurrence_finder = self._create_finder(imports)
+        source = rename.rename_in_module(
+            occurrence_finder, new_name, replace_primary=True,
+            pymodule=pymodule, resource=resource)
+        return source
+
+    def occurs_in_module(self, pymodule=None, resource=None, imports=True):
+        finder = self._create_finder(imports)
+        for occurrence in finder.find_occurrences(pymodule=pymodule,
+                                                  resource=resource):
+            return True
+        return False
+
+    def _create_finder(self, imports):
+        return occurrences.create_finder(self.pycore, self.old_name,
+                                         self.old_pyname, imports=imports)
+
+    def new_pymodule(self, pymodule, source):
+        if source is not None:
+            return self.pycore.get_string_module(
+                source, pymodule.get_resource())
+        return pymodule
+
+    def new_source(self, pymodule, source):
+        if source is None:
+            return pymodule.source_code
+        return source
+
+    def add_imports(self, pymodule, new_imports):
+        return _add_imports_to_module(self.import_tools, pymodule, new_imports)
+
+
+def _add_imports_to_module(import_tools, pymodule, new_imports):
+    module_with_imports = import_tools.module_imports(pymodule)
+    for new_import in new_imports:
+        module_with_imports.add_import(new_import)
+    return module_with_imports.get_changed_source()
+
+
+def moving_code_with_imports(pycore, resource, source):
+    import_tools = importutils.ImportTools(pycore)
+    pymodule = pycore.get_string_module(source, resource)
+    origin = pycore.resource_to_pyobject(resource)
+
+    imports = []
+    for stmt in import_tools.module_imports(origin).imports:
+        imports.append(stmt.import_info)
+
+    back_names = []
+    for name in origin:
+        if name not in pymodule:
+            back_names.append(name)
+    imports.append(import_tools.get_from_import(resource, back_names))
+
+    source = _add_imports_to_module(import_tools, pymodule, imports)
+    pymodule = pycore.get_string_module(source, resource)
+
+    source = import_tools.relatives_to_absolutes(pymodule)
+    pymodule = pycore.get_string_module(source, resource)
+    source = import_tools.organize_imports(pymodule, selfs=False)
+    pymodule = pycore.get_string_module(source, resource)
+
+    # extracting imports after changes
+    module_imports = import_tools.module_imports(pymodule)
+    imports = [import_stmt.import_info
+               for import_stmt in module_imports.imports]
+    start = 1
+    if module_imports.imports:
+        start = module_imports.imports[-1].end_line
+    lines = codeanalyze.SourceLinesAdapter(source)
+    while start < lines.length() and not lines.get_line(start).strip():
+        start += 1
+    moving = source[lines.get_line_start(start):]
+    return moving, imports
+
+
+class ModuleSkipRenamerHandle(object):
+
+    def occurred_outside_skip(self, change_collector, occurrence):
+        pass
+
+    def occurred_inside_skip(self, change_collector, occurrence):
+        pass
+
+
+class ModuleSkipRenamer(object):
+    """Rename occurrences in a module
+
+    This class can be used when you want to treat a region in a file
+    separately from other parts when renaming.
+
+    """
+
+    def __init__(self, occurrence_finder, resource, handle=None,
+                 skip_start=0, skip_end=0, replacement=''):
+        """Constructor
+
+        if replacement is `None` the region is not changed.  Otherwise
+        it is replaced with `replacement`.
+
+        """
+        self.occurrence_finder = occurrence_finder
+        self.resource = resource
+        self.skip_start = skip_start
+        self.skip_end = skip_end
+        self.replacement = replacement
+        self.handle = handle
+        if self.handle is None:
+            self.handle = ModuleSkipHandle()
+
+    def get_changed_module(self):
+        source = self.resource.read()
+        change_collector = codeanalyze.ChangeCollector(source)
+        if self.replacement is not None:
+            change_collector.add_change(self.skip_start, self.skip_end,
+                                        self.replacement)
+        for occurrence in self.occurrence_finder.find_occurrences(self.resource):
+            start, end = occurrence.get_primary_range()
+            if self.skip_start <= start < self.skip_end:
+                self.handle.occurred_inside_skip(change_collector, occurrence)
+            else:
+                self.handle.occurred_outside_skip(change_collector, occurrence)
+        result = change_collector.get_changed()
+        if result is not None and result != source:
+            return result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/multiproject.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,78 @@
+"""This module can be used for performing cross-project refactorings
+
+See the "cross-project refactorings" section of ``docs/library.txt``
+file.
+
+"""
+
+from rope.base import resources, project, libutils
+
+
+class MultiProjectRefactoring(object):
+
+    def __init__(self, refactoring, projects, addpath=True):
+        """Create a multiproject proxy for the main refactoring
+
+        `projects` are other project.
+
+        """
+        self.refactoring = refactoring
+        self.projects = projects
+        self.addpath = addpath
+
+    def __call__(self, project, *args, **kwds):
+        """Create the refactoring"""
+        return _MultiRefactoring(self.refactoring, self.projects,
+                                 self.addpath, project, *args, **kwds)
+
+
+class _MultiRefactoring(object):
+
+    def __init__(self, refactoring, other_projects, addpath,
+                 project, *args, **kwds):
+        self.refactoring = refactoring
+        self.projects = [project] + other_projects
+        for other_project in other_projects:
+            for folder in self.project.pycore.get_source_folders():
+                other_project.get_prefs().add('python_path', folder.real_path)
+        self.refactorings = []
+        for other in self.projects:
+            args, kwds = self._resources_for_args(other, args, kwds)
+            self.refactorings.append(
+                self.refactoring(other, *args, **kwds))
+
+    def get_all_changes(self, *args, **kwds):
+        """Get a project to changes dict"""
+        result = []
+        for project, refactoring in zip(self.projects, self.refactorings):
+            args, kwds = self._resources_for_args(project, args, kwds)
+            result.append((project, refactoring.get_changes(*args, **kwds)))
+        return result
+
+    def __getattr__(self, name):
+        return getattr(self.main_refactoring, name)
+
+    def _resources_for_args(self, project, args, kwds):
+        newargs = [self._change_project_resource(project, arg) for arg in args]
+        newkwds = dict((name, self._change_project_resource(project, value))
+                       for name, value in kwds.items())
+        return newargs, newkwds
+        
+    def _change_project_resource(self, project, obj):
+        if isinstance(obj, resources.Resource) and \
+           obj.project != project:
+            return libutils.path_to_resource(project, obj.real_path)
+        return obj
+
+    @property
+    def project(self):
+        return self.projects[0]
+
+    @property
+    def main_refactoring(self):
+        return self.refactorings[0]
+
+
+def perform(project_changes):
+    for project, changes in project_changes:
+        project.do(changes)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/occurrences.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,334 @@
+import re
+
+import rope.base.pynames
+from rope.base import pynames, pyobjects, codeanalyze, evaluate, exceptions, utils, worder
+
+
+class Finder(object):
+    """For finding occurrences of a name
+
+    The constructor takes a `filters` argument.  It should be a list
+    of functions that take a single argument.  For each possible
+    occurrence, these functions are called in order with the an
+    instance of `Occurrence`:
+
+      * If it returns `None` other filters are tried.
+      * If it returns `True`, the occurrence will be a match.
+      * If it returns `False`, the occurrence will be skipped.
+      * If all of the filters return `None`, it is skipped also.
+
+    """
+
+    def __init__(self, pycore, name, filters=[lambda o: True], docs=False):
+        self.pycore = pycore
+        self.name = name
+        self.docs = docs
+        self.filters = filters
+        self._textual_finder = _TextualFinder(name, docs=docs)
+
+    def find_occurrences(self, resource=None, pymodule=None):
+        """Generate `Occurrence` instances"""
+        tools = _OccurrenceToolsCreator(self.pycore, resource=resource,
+                                        pymodule=pymodule, docs=self.docs)
+        for offset in self._textual_finder.find_offsets(tools.source_code):
+            occurrence = Occurrence(tools, offset)
+            for filter in self.filters:
+                result = filter(occurrence)
+                if result is None:
+                    continue
+                if result:
+                    yield occurrence
+                break
+
+
+def create_finder(pycore, name, pyname, only_calls=False, imports=True,
+                  unsure=None, docs=False, instance=None, in_hierarchy=False):
+    """A factory for `Finder`
+
+    Based on the arguments it creates a list of filters.  `instance`
+    argument is needed only when you want implicit interfaces to be
+    considered.
+
+    """
+    pynames = set([pyname])
+    filters = []
+    if only_calls:
+        filters.append(CallsFilter())
+    if not imports:
+        filters.append(NoImportsFilter())
+    if isinstance(instance, rope.base.pynames.ParameterName):
+        for pyobject in instance.get_objects():
+            try:
+                pynames.add(pyobject[name])
+            except exceptions.AttributeNotFoundError:
+                pass
+    for pyname in pynames:
+        filters.append(PyNameFilter(pyname))
+        if in_hierarchy:
+            filters.append(InHierarchyFilter(pyname))
+    if unsure:
+        filters.append(UnsureFilter(unsure))
+    return Finder(pycore, name, filters=filters, docs=docs)
+
+
+class Occurrence(object):
+
+    def __init__(self, tools, offset):
+        self.tools = tools
+        self.offset = offset
+        self.resource = tools.resource
+
+    @utils.saveit
+    def get_word_range(self):
+        return self.tools.word_finder.get_word_range(self.offset)
+
+    @utils.saveit
+    def get_primary_range(self):
+        return self.tools.word_finder.get_primary_range(self.offset)
+
+    @utils.saveit
+    def get_pyname(self):
+        try:
+            return self.tools.name_finder.get_pyname_at(self.offset)
+        except exceptions.BadIdentifierError:
+            pass
+
+    @utils.saveit
+    def get_primary_and_pyname(self):
+        try:
+            return self.tools.name_finder.get_primary_and_pyname_at(self.offset)
+        except exceptions.BadIdentifierError:
+            pass
+
+    @utils.saveit
+    def is_in_import_statement(self):
+        return (self.tools.word_finder.is_from_statement(self.offset) or
+                self.tools.word_finder.is_import_statement(self.offset))
+
+    def is_called(self):
+        return self.tools.word_finder.is_a_function_being_called(self.offset)
+
+    def is_defined(self):
+        return self.tools.word_finder.is_a_class_or_function_name_in_header(self.offset)
+
+    def is_a_fixed_primary(self):
+        return self.tools.word_finder.is_a_class_or_function_name_in_header(self.offset) or \
+               self.tools.word_finder.is_a_name_after_from_import(self.offset)
+
+    def is_written(self):
+        return self.tools.word_finder.is_assigned_here(self.offset)
+
+    def is_unsure(self):
+        return unsure_pyname(self.get_pyname())
+
+    @property
+    @utils.saveit
+    def lineno(self):
+        offset = self.get_word_range()[0]
+        return self.tools.pymodule.lines.get_line_number(offset)
+
+
+def same_pyname(expected, pyname):
+    """Check whether `expected` and `pyname` are the same"""
+    if expected is None or pyname is None:
+        return False
+    if expected == pyname:
+        return True
+    if type(expected) not in (pynames.ImportedModule, pynames.ImportedName) and \
+       type(pyname) not in (pynames.ImportedModule, pynames.ImportedName):
+        return False
+    return expected.get_definition_location() == pyname.get_definition_location() and \
+           expected.get_object() == pyname.get_object()
+
+def unsure_pyname(pyname, unbound=True):
+    """Return `True` if we don't know what this name references"""
+    if pyname is None:
+        return True
+    if unbound and not isinstance(pyname, pynames.UnboundName):
+        return False
+    if pyname.get_object() == pyobjects.get_unknown():
+        return True
+
+
+class PyNameFilter(object):
+    """For finding occurrences of a name"""
+
+    def __init__(self, pyname):
+        self.pyname = pyname
+
+    def __call__(self, occurrence):
+        if same_pyname(self.pyname, occurrence.get_pyname()):
+            return True
+
+
+class InHierarchyFilter(object):
+    """For finding occurrences of a name"""
+
+    def __init__(self, pyname, implementations_only=False):
+        self.pyname = pyname
+        self.impl_only = implementations_only
+        self.pyclass = self._get_containing_class(pyname)
+        if self.pyclass is not None:
+            self.name = pyname.get_object().get_name()
+            self.roots = self._get_root_classes(self.pyclass, self.name)
+        else:
+            self.roots = None
+
+    def __call__(self, occurrence):
+        if self.roots is None:
+            return
+        pyclass = self._get_containing_class(occurrence.get_pyname())
+        if pyclass is not None:
+            roots = self._get_root_classes(pyclass, self.name)
+            if self.roots.intersection(roots):
+                return True
+
+    def _get_containing_class(self, pyname):
+        if isinstance(pyname, pynames.DefinedName):
+            scope = pyname.get_object().get_scope()
+            parent = scope.parent
+            if parent is not None and parent.get_kind() == 'Class':
+                return parent.pyobject
+
+    def _get_root_classes(self, pyclass, name):
+        if self.impl_only and pyclass == self.pyclass:
+            return set([pyclass])
+        result = set()
+        for superclass in pyclass.get_superclasses():
+            if name in superclass:
+                result.update(self._get_root_classes(superclass, name))
+        if not result:
+            return set([pyclass])
+        return result
+
+
+class UnsureFilter(object):
+
+    def __init__(self, unsure):
+        self.unsure = unsure
+
+    def __call__(self, occurrence):
+        if occurrence.is_unsure() and self.unsure(occurrence):
+            return True
+
+
+class NoImportsFilter(object):
+
+    def __call__(self, occurrence):
+        if occurrence.is_in_import_statement():
+            return False
+
+
+class CallsFilter(object):
+
+    def __call__(self, occurrence):
+        if not occurrence.is_called():
+            return False
+
+
+class _TextualFinder(object):
+
+    def __init__(self, name, docs=False):
+        self.name = name
+        self.docs = docs
+        self.comment_pattern = _TextualFinder.any('comment', [r'#[^\n]*'])
+        self.string_pattern = _TextualFinder.any(
+            'string', [codeanalyze.get_string_pattern()])
+        self.pattern = self._get_occurrence_pattern(self.name)
+
+    def find_offsets(self, source):
+        if not self._fast_file_query(source):
+            return
+        if self.docs:
+            searcher = self._normal_search
+        else:
+            searcher = self._re_search
+        for matched in searcher(source):
+            yield matched
+
+    def _re_search(self, source):
+        for match in self.pattern.finditer(source):
+            for key, value in match.groupdict().items():
+                if value and key == 'occurrence':
+                    yield match.start(key)
+
+    def _normal_search(self, source):
+        current = 0
+        while True:
+            try:
+                found = source.index(self.name, current)
+                current = found + len(self.name)
+                if (found == 0 or not self._is_id_char(source[found - 1])) and \
+                   (current == len(source) or not self._is_id_char(source[current])):
+                    yield found
+            except ValueError:
+                break
+
+    def _is_id_char(self, c):
+        return c.isalnum() or c == '_'
+
+    def _fast_file_query(self, source):
+        try:
+            source.index(self.name)
+            return True
+        except ValueError:
+            return False
+
+    def _get_source(self, resource, pymodule):
+        if resource is not None:
+            return resource.read()
+        else:
+            return pymodule.source_code
+
+    def _get_occurrence_pattern(self, name):
+        occurrence_pattern = _TextualFinder.any('occurrence',
+                                                 ['\\b' + name + '\\b'])
+        pattern = re.compile(occurrence_pattern + '|' + self.comment_pattern +
+                             '|' + self.string_pattern)
+        return pattern
+
+    @staticmethod
+    def any(name, list_):
+        return '(?P<%s>' % name + '|'.join(list_) + ')'
+
+
+class _OccurrenceToolsCreator(object):
+
+    def __init__(self, pycore, resource=None, pymodule=None, docs=False):
+        self.pycore = pycore
+        self.__resource = resource
+        self.__pymodule = pymodule
+        self.docs = docs
+
+    @property
+    @utils.saveit
+    def name_finder(self):
+        return evaluate.ScopeNameFinder(self.pymodule)
+
+    @property
+    @utils.saveit
+    def source_code(self):
+        if self.__resource is not None:
+            return self.resource.read()
+        else:
+            return self.pymodule.source_code
+
+    @property
+    @utils.saveit
+    def word_finder(self):
+        return worder.Worder(self.source_code, self.docs)
+
+    @property
+    @utils.saveit
+    def resource(self):
+        if self.__resource is not None:
+            return self.__resource
+        if self.__pymodule is not None:
+            return self.__pymodule.resource
+
+    @property
+    @utils.saveit
+    def pymodule(self):
+        if self.__pymodule is not None:
+            return self.__pymodule
+        return self.pycore.resource_to_pyobject(self.resource)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/patchedast.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,732 @@
+import collections
+import re
+import warnings
+
+from rope.base import ast, codeanalyze, exceptions
+
+
+def get_patched_ast(source, sorted_children=False):
+    """Adds ``region`` and ``sorted_children`` fields to nodes
+
+    Adds ``sorted_children`` field only if `sorted_children` is True.
+
+    """
+    return patch_ast(ast.parse(source), source, sorted_children)
+
+
+def patch_ast(node, source, sorted_children=False):
+    """Patches the given node
+
+    After calling, each node in `node` will have a new field named
+    `region` that is a tuple containing the start and end offsets
+    of the code that generated it.
+
+    If `sorted_children` is true, a `sorted_children` field will
+    be created for each node, too.  It is a list containing child
+    nodes as well as whitespaces and comments that occur between
+    them.
+
+    """
+    if hasattr(node, 'region'):
+        return node
+    walker = _PatchingASTWalker(source, children=sorted_children)
+    ast.call_for_nodes(node, walker)
+    return node
+
+
+def node_region(patched_ast_node):
+    """Get the region of a patched ast node"""
+    return patched_ast_node.region
+
+
+def write_ast(patched_ast_node):
+    """Extract source form a patched AST node with `sorted_children` field
+
+    If the node is patched with sorted_children turned off you can use
+    `node_region` function for obtaining code using module source code.
+    """
+    result = []
+    for child in patched_ast_node.sorted_children:
+        if isinstance(child, ast.AST):
+            result.append(write_ast(child))
+        else:
+            result.append(child)
+    return ''.join(result)
+
+
+class MismatchedTokenError(exceptions.RopeError):
+    pass
+
+
+class _PatchingASTWalker(object):
+
+    def __init__(self, source, children=False):
+        self.source = _Source(source)
+        self.children = children
+        self.lines = codeanalyze.SourceLinesAdapter(source)
+        self.children_stack = []
+
+    Number = object()
+    String = object()
+
+    def __call__(self, node):
+        method = getattr(self, '_' + node.__class__.__name__, None)
+        if method is not None:
+            return method(node)
+        # ???: Unknown node; what should we do here?
+        warnings.warn('Unknown node type <%s>; please report!'
+                      % node.__class__.__name__, RuntimeWarning)
+        node.region = (self.source.offset, self.source.offset)
+        if self.children:
+            node.sorted_children = ast.get_children(node)
+
+    def _handle(self, node, base_children, eat_parens=False, eat_spaces=False):
+        if hasattr(node, 'region'):
+            # ???: The same node was seen twice; what should we do?
+            warnings.warn(
+                'Node <%s> has been already patched; please report!' %
+                node.__class__.__name__, RuntimeWarning)
+            return
+        base_children = collections.deque(base_children)
+        self.children_stack.append(base_children)
+        children = collections.deque()
+        formats = []
+        suspected_start = self.source.offset
+        start = suspected_start
+        first_token = True
+        while base_children:
+            child = base_children.popleft()
+            if child is None:
+                continue
+            offset = self.source.offset
+            if isinstance(child, ast.AST):
+                ast.call_for_nodes(child, self)
+                token_start = child.region[0]
+            else:
+                if child is self.String:
+                    region = self.source.consume_string(
+                        end=self._find_next_statement_start())
+                elif child is self.Number:
+                    region = self.source.consume_number()
+                elif child == '!=':
+                    # INFO: This has been added to handle deprecated ``<>``
+                    region = self.source.consume_not_equal()
+                else:
+                    region = self.source.consume(child)
+                child = self.source[region[0]:region[1]]
+                token_start = region[0]
+            if not first_token:
+                formats.append(self.source[offset:token_start])
+                if self.children:
+                    children.append(self.source[offset:token_start])
+            else:
+                first_token = False
+                start = token_start
+            if self.children:
+                children.append(child)
+        start = self._handle_parens(children, start, formats)
+        if eat_parens:
+            start = self._eat_surrounding_parens(
+                children, suspected_start, start)
+        if eat_spaces:
+            if self.children:
+                children.appendleft(self.source[0:start])
+            end_spaces = self.source[self.source.offset:]
+            self.source.consume(end_spaces)
+            if self.children:
+                children.append(end_spaces)
+            start = 0
+        if self.children:
+            node.sorted_children = children
+        node.region = (start, self.source.offset)
+        self.children_stack.pop()
+
+    def _handle_parens(self, children, start, formats):
+        """Changes `children` and returns new start"""
+        opens, closes = self._count_needed_parens(formats)
+        old_end = self.source.offset
+        new_end = None
+        for i in range(closes):
+            new_end = self.source.consume(')')[1]
+        if new_end is not None:
+            if self.children:
+                children.append(self.source[old_end:new_end])
+        new_start = start
+        for i in range(opens):
+            new_start = self.source.rfind_token('(', 0, new_start)
+        if new_start != start:
+            if self.children:
+                children.appendleft(self.source[new_start:start])
+            start = new_start
+        return start
+
+    def _eat_surrounding_parens(self, children, suspected_start, start):
+        index = self.source.rfind_token('(', suspected_start, start)
+        if index is not None:
+            old_start = start
+            old_offset = self.source.offset
+            start = index
+            if self.children:
+                children.appendleft(self.source[start + 1:old_start])
+                children.appendleft('(')
+            token_start, token_end = self.source.consume(')')
+            if self.children:
+                children.append(self.source[old_offset:token_start])
+                children.append(')')
+        return start
+
+    def _count_needed_parens(self, children):
+        start = 0
+        opens = 0
+        for child in children:
+            if not isinstance(child, basestring):
+                continue
+            if child == '' or child[0] in '\'"':
+                continue
+            index = 0
+            while index < len(child):
+                if child[index] == ')':
+                    if opens > 0:
+                        opens -= 1
+                    else:
+                        start += 1
+                if child[index] == '(':
+                    opens += 1
+                if child[index] == '#':
+                    try:
+                        index = child.index('\n', index)
+                    except ValueError:
+                        break
+                index += 1
+        return start, opens
+
+    def _find_next_statement_start(self):
+        for children in reversed(self.children_stack):
+            for child in children:
+                if isinstance(child, ast.stmt):
+                    return self.lines.get_line_start(child.lineno)
+        return len(self.source.source)
+
+    _operators = {'And': 'and', 'Or': 'or', 'Add': '+', 'Sub': '-', 'Mult': '*',
+                  'Div': '/', 'Mod': '%', 'Pow': '**', 'LShift': '<<',
+                  'RShift': '>>', 'BitOr': '|', 'BitAnd': '&', 'BitXor': '^',
+                  'FloorDiv': '//', 'Invert': '~', 'Not': 'not', 'UAdd': '+',
+                  'USub': '-', 'Eq': '==', 'NotEq': '!=', 'Lt': '<',
+                  'LtE': '<=', 'Gt': '>', 'GtE': '>=', 'Is': 'is',
+                  'IsNot': 'is not', 'In': 'in', 'NotIn': 'not in'}
+
+    def _get_op(self, node):
+        return self._operators[node.__class__.__name__].split(' ')
+
+    def _Attribute(self, node):
+        self._handle(node, [node.value, '.', node.attr])
+
+    def _Assert(self, node):
+        children = ['assert', node.test]
+        if node.msg:
+            children.append(',')
+            children.append(node.msg)
+        self._handle(node, children)
+
+    def _Assign(self, node):
+        children = self._child_nodes(node.targets, '=')
+        children.append('=')
+        children.append(node.value)
+        self._handle(node, children)
+
+    def _AugAssign(self, node):
+        children = [node.target]
+        children.extend(self._get_op(node.op))
+        children.extend(['=', node.value])
+        self._handle(node, children)
+
+    def _Repr(self, node):
+        self._handle(node, ['`', node.value, '`'])
+
+    def _BinOp(self, node):
+        children = [node.left] + self._get_op(node.op) + [node.right]
+        self._handle(node, children)
+
+    def _BoolOp(self, node):
+        self._handle(node, self._child_nodes(node.values,
+                                             self._get_op(node.op)[0]))
+
+    def _Break(self, node):
+        self._handle(node, ['break'])
+
+    def _Call(self, node):
+        children = [node.func, '(']
+        args = list(node.args) + node.keywords
+        children.extend(self._child_nodes(args, ','))
+        if node.starargs is not None:
+            if args:
+                children.append(',')
+            children.extend(['*', node.starargs])
+        if node.kwargs is not None:
+            if args or node.starargs is not None:
+                children.append(',')
+            children.extend(['**', node.kwargs])
+        children.append(')')
+        self._handle(node, children)
+
+    def _ClassDef(self, node):
+        children = []
+        if getattr(node, 'decorator_list', None):
+            for decorator in node.decorator_list:
+                children.append('@')
+                children.append(decorator)
+        children.extend(['class', node.name])
+        if node.bases:
+            children.append('(')
+            children.extend(self._child_nodes(node.bases, ','))
+            children.append(')')
+        children.append(':')
+        children.extend(node.body)
+        self._handle(node, children)
+
+    def _Compare(self, node):
+        children = []
+        children.append(node.left)
+        for op, expr in zip(node.ops, node.comparators):
+            children.extend(self._get_op(op))
+            children.append(expr)
+        self._handle(node, children)
+
+    def _Delete(self, node):
+        self._handle(node, ['del'] + self._child_nodes(node.targets, ','))
+
+    def _Num(self, node):
+        self._handle(node, [self.Number])
+
+    def _Str(self, node):
+        self._handle(node, [self.String])
+
+    def _Continue(self, node):
+        self._handle(node, ['continue'])
+
+    def _Dict(self, node):
+        children = []
+        children.append('{')
+        if node.keys:
+            for index, (key, value) in enumerate(zip(node.keys, node.values)):
+                children.extend([key, ':', value])
+                if index < len(node.keys) - 1:
+                    children.append(',')
+        children.append('}')
+        self._handle(node, children)
+
+    def _Ellipsis(self, node):
+        self._handle(node, ['...'])
+
+    def _Expr(self, node):
+        self._handle(node, [node.value])
+
+    def _Exec(self, node):
+        children = []
+        children.extend(['exec', node.body])
+        if node.globals:
+            children.extend(['in', node.globals])
+        if node.locals:
+            children.extend([',', node.locals])
+        self._handle(node, children)
+
+    def _ExtSlice(self, node):
+        children = []
+        for index, dim in enumerate(node.dims):
+            if index > 0:
+                children.append(',')
+            children.append(dim)
+        self._handle(node, children)
+
+    def _For(self, node):
+        children = ['for', node.target, 'in', node.iter, ':']
+        children.extend(node.body)
+        if node.orelse:
+            children.extend(['else', ':'])
+            children.extend(node.orelse)
+        self._handle(node, children)
+
+    def _ImportFrom(self, node):
+        children = ['from']
+        if node.level:
+            children.append('.' * node.level)
+        children.extend([node.module, 'import'])
+        children.extend(self._child_nodes(node.names, ','))
+        self._handle(node, children)
+
+    def _alias(self, node):
+        children = [node.name]
+        if node.asname:
+            children.extend(['as', node.asname])
+        self._handle(node, children)
+
+    def _FunctionDef(self, node):
+        children = []
+        try:
+            decorators = getattr(node, 'decorator_list')
+        except AttributeError:
+            decorators = getattr(node, 'decorators', None)
+        if decorators:
+            for decorator in decorators:
+                children.append('@')
+                children.append(decorator)
+        children.extend(['def', node.name, '(', node.args])
+        children.extend([')', ':'])
+        children.extend(node.body)
+        self._handle(node, children)
+
+    def _arguments(self, node):
+        children = []
+        args = list(node.args)
+        defaults = [None] * (len(args) - len(node.defaults)) + list(node.defaults)
+        for index, (arg, default) in enumerate(zip(args, defaults)):
+            if index > 0:
+                children.append(',')
+            self._add_args_to_children(children, arg, default)
+        if node.vararg is not None:
+            if args:
+                children.append(',')
+            children.extend(['*', node.vararg])
+        if node.kwarg is not None:
+            if args or node.vararg is not None:
+                children.append(',')
+            children.extend(['**', node.kwarg])
+        self._handle(node, children)
+
+    def _add_args_to_children(self, children, arg, default):
+        if isinstance(arg, (list, tuple)):
+            self._add_tuple_parameter(children, arg)
+        else:
+            children.append(arg)
+        if default is not None:
+            children.append('=')
+            children.append(default)
+
+    def _add_tuple_parameter(self, children, arg):
+        children.append('(')
+        for index, token in enumerate(arg):
+            if index > 0:
+                children.append(',')
+            if isinstance(token, (list, tuple)):
+                self._add_tuple_parameter(children, token)
+            else:
+                children.append(token)
+        children.append(')')
+
+    def _GeneratorExp(self, node):
+        children = [node.elt]
+        children.extend(node.generators)
+        self._handle(node, children, eat_parens=True)
+
+    def _comprehension(self, node):
+        children = ['for', node.target, 'in', node.iter]
+        if node.ifs:
+            for if_ in node.ifs:
+                children.append('if')
+                children.append(if_)
+        self._handle(node, children)
+
+    def _Global(self, node):
+        children = self._child_nodes(node.names, ',')
+        children.insert(0, 'global')
+        self._handle(node, children)
+
+    def _If(self, node):
+        if self._is_elif(node):
+            children = ['elif']
+        else:
+            children = ['if']
+        children.extend([node.test, ':'])
+        children.extend(node.body)
+        if node.orelse:
+            if len(node.orelse) == 1 and self._is_elif(node.orelse[0]):
+                pass
+            else:
+                children.extend(['else', ':'])
+            children.extend(node.orelse)
+        self._handle(node, children)
+
+    def _is_elif(self, node):
+        if not isinstance(node, ast.If):
+            return False
+        offset = self.lines.get_line_start(node.lineno) + node.col_offset
+        word = self.source[offset:offset + 4]
+        # XXX: This is a bug; the offset does not point to the first
+        alt_word = self.source[offset - 5:offset - 1]
+        return 'elif' in (word, alt_word)
+
+    def _IfExp(self, node):
+        return self._handle(node, [node.body, 'if', node.test,
+                                   'else', node.orelse])
+
+    def _Import(self, node):
+        children = ['import']
+        children.extend(self._child_nodes(node.names, ','))
+        self._handle(node, children)
+
+    def _keyword(self, node):
+        self._handle(node, [node.arg, '=', node.value])
+
+    def _Lambda(self, node):
+        self._handle(node, ['lambda', node.args, ':', node.body])
+
+    def _List(self, node):
+        self._handle(node, ['['] + self._child_nodes(node.elts, ',') + [']'])
+
+    def _ListComp(self, node):
+        children = ['[', node.elt]
+        children.extend(node.generators)
+        children.append(']')
+        self._handle(node, children)
+
+    def _Module(self, node):
+        self._handle(node, list(node.body), eat_spaces=True)
+
+    def _Name(self, node):
+        self._handle(node, [node.id])
+
+    def _Pass(self, node):
+        self._handle(node, ['pass'])
+
+    def _Print(self, node):
+        children = ['print']
+        if node.dest:
+            children.extend(['>>', node.dest])
+            if node.values:
+                children.append(',')
+        children.extend(self._child_nodes(node.values, ','))
+        if not node.nl:
+            children.append(',')
+        self._handle(node, children)
+
+    def _Raise(self, node):
+        children = ['raise']
+        if node.type:
+            children.append(node.type)
+        if node.inst:
+            children.append(',')
+            children.append(node.inst)
+        if node.tback:
+            children.append(',')
+            children.append(node.tback)
+        self._handle(node, children)
+
+    def _Return(self, node):
+        children = ['return']
+        if node.value:
+            children.append(node.value)
+        self._handle(node, children)
+
+    def _Sliceobj(self, node):
+        children = []
+        for index, slice in enumerate(node.nodes):
+            if index > 0:
+                children.append(':')
+            if slice:
+                children.append(slice)
+        self._handle(node, children)
+
+    def _Index(self, node):
+        self._handle(node, [node.value])
+
+    def _Subscript(self, node):
+        self._handle(node, [node.value, '[', node.slice, ']'])
+
+    def _Slice(self, node):
+        children = []
+        if node.lower:
+            children.append(node.lower)
+        children.append(':')
+        if node.upper:
+            children.append(node.upper)
+        if node.step:
+            children.append(':')
+            children.append(node.step)
+        self._handle(node, children)
+
+    def _TryFinally(self, node):
+        children = []
+        if len(node.body) != 1 or not isinstance(node.body[0], ast.TryExcept):
+            children.extend(['try', ':'])
+        children.extend(node.body)
+        children.extend(['finally', ':'])
+        children.extend(node.finalbody)
+        self._handle(node, children)
+
+    def _TryExcept(self, node):
+        children = ['try', ':']
+        children.extend(node.body)
+        children.extend(node.handlers)
+        if node.orelse:
+            children.extend(['else', ':'])
+            children.extend(node.orelse)
+        self._handle(node, children)
+
+    def _ExceptHandler(self, node):
+        self._excepthandler(node)
+
+    def _excepthandler(self, node):
+        children = ['except']
+        if node.type:
+            children.append(node.type)
+        if node.name:
+            children.extend([',', node.name])
+        children.append(':')
+        children.extend(node.body)
+        self._handle(node, children)
+
+    def _Tuple(self, node):
+        if node.elts:
+            self._handle(node, self._child_nodes(node.elts, ','),
+                         eat_parens=True)
+        else:
+            self._handle(node, ['(', ')'])
+
+    def _UnaryOp(self, node):
+        children = self._get_op(node.op)
+        children.append(node.operand)
+        self._handle(node, children)
+
+    def _Yield(self, node):
+        children = ['yield']
+        if node.value:
+            children.append(node.value)
+        self._handle(node, children)
+
+    def _While(self, node):
+        children = ['while', node.test, ':']
+        children.extend(node.body)
+        if node.orelse:
+            children.extend(['else', ':'])
+            children.extend(node.orelse)
+        self._handle(node, children)
+
+    def _With(self, node):
+        children = ['with', node.context_expr]
+        if node.optional_vars:
+            children.extend(['as', node.optional_vars])
+        children.append(':')
+        children.extend(node.body)
+        self._handle(node, children)
+
+    def _child_nodes(self, nodes, separator):
+        children = []
+        for index, child in enumerate(nodes):
+            children.append(child)
+            if index < len(nodes) - 1:
+                children.append(separator)
+        return children
+
+
+class _Source(object):
+
+    def __init__(self, source):
+        self.source = source
+        self.offset = 0
+
+    def consume(self, token):
+        try:
+            while True:
+                new_offset = self.source.index(token, self.offset)
+                if self._good_token(token, new_offset):
+                    break
+                else:
+                    self._skip_comment()
+        except (ValueError, TypeError):
+            raise MismatchedTokenError(
+                'Token <%s> at %s cannot be matched' %
+                (token, self._get_location()))
+        self.offset = new_offset + len(token)
+        return (new_offset, self.offset)
+
+    def consume_string(self, end=None):
+        if _Source._string_pattern is None:
+            original = codeanalyze.get_string_pattern()
+            pattern = r'(%s)((\s|\\\n|#[^\n]*\n)*(%s))*' % \
+                      (original, original)
+            _Source._string_pattern = re.compile(pattern)
+        repattern = _Source._string_pattern
+        return self._consume_pattern(repattern, end)
+
+    def consume_number(self):
+        if _Source._number_pattern is None:
+            _Source._number_pattern = re.compile(
+                self._get_number_pattern())
+        repattern = _Source._number_pattern
+        return self._consume_pattern(repattern)
+
+    def consume_not_equal(self):
+        if _Source._not_equals_pattern is None:
+            _Source._not_equals_pattern = re.compile(r'<>|!=')
+        repattern = _Source._not_equals_pattern
+        return self._consume_pattern(repattern)
+
+    def _good_token(self, token, offset, start=None):
+        """Checks whether consumed token is in comments"""
+        if start is None:
+            start = self.offset
+        try:
+            comment_index = self.source.rindex('#', start, offset)
+        except ValueError:
+            return True
+        try:
+            new_line_index = self.source.rindex('\n', start, offset)
+        except ValueError:
+            return False
+        return comment_index < new_line_index
+
+    def _skip_comment(self):
+        self.offset = self.source.index('\n', self.offset + 1)
+
+    def _get_location(self):
+        lines = self.source[:self.offset].split('\n')
+        return (len(lines), len(lines[-1]))
+
+    def _consume_pattern(self, repattern, end=None):
+        while True:
+            if end is None:
+                end = len(self.source)
+            match = repattern.search(self.source, self.offset, end)
+            if self._good_token(match.group(), match.start()):
+                break
+            else:
+                self._skip_comment()
+        self.offset = match.end()
+        return match.start(), match.end()
+
+    def till_token(self, token):
+        new_offset = self.source.index(token, self.offset)
+        return self[self.offset:new_offset]
+
+    def rfind_token(self, token, start, end):
+        index = start
+        while True:
+            try:
+                index = self.source.rindex(token, start, end)
+                if self._good_token(token, index, start=start):
+                    return index
+                else:
+                    end = index
+            except ValueError:
+                return None
+
+    def from_offset(self, offset):
+        return self[offset:self.offset]
+
+    def find_backwards(self, pattern, offset):
+        return self.source.rindex(pattern, 0, offset)
+
+    def __getitem__(self, index):
+        return self.source[index]
+
+    def __getslice__(self, i, j):
+        return self.source[i:j]
+
+    def _get_number_pattern(self):
+        # HACK: It is merely an approaximation and does the job
+        integer = r'(0|0x)?[\da-fA-F]+[lL]?'
+        return r'(%s(\.\d*)?|(\.\d+))([eE][-+]?\d*)?[jJ]?' % integer
+
+    _string_pattern = None
+    _number_pattern = None
+    _not_equals_pattern = None
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/rename.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,216 @@
+import warnings
+
+from rope.base import exceptions, pyobjects, pynames, taskhandle, evaluate, worder, codeanalyze
+from rope.base.change import ChangeSet, ChangeContents, MoveResource
+from rope.refactor import occurrences, sourceutils
+
+
+class Rename(object):
+    """A class for performing rename refactoring
+
+    It can rename everything: classes, functions, modules, packages,
+    methods, variables and keyword arguments.
+
+    """
+
+    def __init__(self, project, resource, offset=None):
+        """If `offset` is None, the `resource` itself will be renamed"""
+        self.project = project
+        self.pycore = project.pycore
+        self.resource = resource
+        if offset is not None:
+            self.old_name = worder.get_name_at(self.resource, offset)
+            this_pymodule = self.pycore.resource_to_pyobject(self.resource)
+            self.old_instance, self.old_pyname = \
+                evaluate.eval_location2(this_pymodule, offset)
+            if self.old_pyname is None:
+                raise exceptions.RefactoringError(
+                    'Rename refactoring should be performed'
+                    ' on resolvable python identifiers.')
+        else:
+            if not resource.is_folder() and resource.name == '__init__.py':
+                resource = resource.parent
+            dummy_pymodule = self.pycore.get_string_module('')
+            self.old_instance = None
+            self.old_pyname = pynames.ImportedModule(dummy_pymodule,
+                                                     resource=resource)
+            if resource.is_folder():
+                self.old_name = resource.name
+            else:
+                self.old_name = resource.name[:-3]
+
+    def get_old_name(self):
+        return self.old_name
+
+    def get_changes(self, new_name, in_file=None, in_hierarchy=False,
+                    unsure=None, docs=False, resources=None,
+                    task_handle=taskhandle.NullTaskHandle()):
+        """Get the changes needed for this refactoring
+
+        Parameters:
+
+        - `in_hierarchy`: when renaming a method this keyword forces
+          to rename all matching methods in the hierarchy
+        - `docs`: when `True` rename refactoring will rename
+          occurrences in comments and strings where the name is
+          visible.  Setting it will make renames faster, too.
+        - `unsure`: decides what to do about unsure occurrences.
+          If `None`, they are ignored.  Otherwise `unsure` is
+          called with an instance of `occurrence.Occurrence` as
+          parameter.  If it returns `True`, the occurrence is
+          considered to be a match.
+        - `resources` can be a list of `rope.base.resources.File`\s to
+          apply this refactoring on.  If `None`, the restructuring
+          will be applied to all python files.
+        - `in_file`: this argument has been deprecated; use
+          `resources` instead.
+
+        """
+        if unsure in (True, False):
+            warnings.warn(
+                'unsure parameter should be a function that returns '
+                'True or False', DeprecationWarning, stacklevel=2)
+            def unsure_func(value=unsure):
+                return value
+            unsure = unsure_func
+        if in_file is not None:
+            warnings.warn(
+                '`in_file` argument has been deprecated; use `resources` '
+                'instead. ', DeprecationWarning, stacklevel=2)
+            if in_file:
+                resources = [self.resource]
+        if _is_local(self.old_pyname):
+            resources = [self.resource]
+        if resources is None:
+            resources = self.pycore.get_python_files()
+        changes = ChangeSet('Renaming <%s> to <%s>' %
+                            (self.old_name, new_name))
+        finder = occurrences.create_finder(
+            self.pycore, self.old_name, self.old_pyname, unsure=unsure,
+            docs=docs, instance=self.old_instance,
+            in_hierarchy=in_hierarchy and self.is_method())
+        job_set = task_handle.create_jobset('Collecting Changes', len(resources))
+        for file_ in resources:
+            job_set.started_job(file_.path)
+            new_content = rename_in_module(finder, new_name, resource=file_)
+            if new_content is not None:
+                changes.add_change(ChangeContents(file_, new_content))
+            job_set.finished_job()
+        if self._is_renaming_a_module():
+            resource = self.old_pyname.get_object().get_resource()
+            if self._is_allowed_to_move(resources, resource):
+                self._rename_module(resource, new_name, changes)
+        return changes
+
+    def _is_allowed_to_move(self, resources, resource):
+        if resource.is_folder():
+            try:
+                return resource.get_child('__init__.py') in resources
+            except exceptions.ResourceNotFoundError:
+                return False
+        else:
+            return resource in resources
+
+    def _is_renaming_a_module(self):
+        if isinstance(self.old_pyname.get_object(), pyobjects.AbstractModule):
+            return True
+        return False
+
+    def is_method(self):
+        pyname = self.old_pyname
+        return isinstance(pyname, pynames.DefinedName) and \
+               isinstance(pyname.get_object(), pyobjects.PyFunction) and \
+               isinstance(pyname.get_object().parent, pyobjects.PyClass)
+
+    def _rename_module(self, resource, new_name, changes):
+        if not resource.is_folder():
+            new_name = new_name + '.py'
+        parent_path = resource.parent.path
+        if parent_path == '':
+            new_location = new_name
+        else:
+            new_location = parent_path + '/' + new_name
+        changes.add_change(MoveResource(resource, new_location))
+
+
+class ChangeOccurrences(object):
+    """A class for changing the occurrences of a name in a scope
+
+    This class replaces the occurrences of a name.  Note that it only
+    changes the scope containing the offset passed to the constructor.
+    What's more it does not have any side-effects.  That is for
+    example changing occurrences of a module does not rename the
+    module; it merely replaces the occurrences of that module in a
+    scope with the given expression.  This class is useful for
+    performing many custom refactorings.
+
+    """
+
+    def __init__(self, project, resource, offset):
+        self.pycore = project.pycore
+        self.resource = resource
+        self.offset = offset
+        self.old_name = worder.get_name_at(resource, offset)
+        self.pymodule = self.pycore.resource_to_pyobject(self.resource)
+        self.old_pyname = evaluate.eval_location(self.pymodule, offset)
+
+    def get_old_name(self):
+        word_finder = worder.Worder(self.resource.read())
+        return word_finder.get_primary_at(self.offset)
+
+    def _get_scope_offset(self):
+        lines = self.pymodule.lines
+        scope = self.pymodule.get_scope().\
+                get_inner_scope_for_line(lines.get_line_number(self.offset))
+        start = lines.get_line_start(scope.get_start())
+        end = lines.get_line_end(scope.get_end())
+        return start, end
+
+    def get_changes(self, new_name, only_calls=False, reads=True, writes=True):
+        changes = ChangeSet('Changing <%s> occurrences to <%s>' %
+                            (self.old_name, new_name))
+        scope_start, scope_end = self._get_scope_offset()
+        finder = occurrences.create_finder(
+            self.pycore, self.old_name, self.old_pyname,
+            imports=False, only_calls=only_calls)
+        new_contents = rename_in_module(
+            finder, new_name, pymodule=self.pymodule, replace_primary=True,
+            region=(scope_start, scope_end), reads=reads, writes=writes)
+        if new_contents is not None:
+            changes.add_change(ChangeContents(self.resource, new_contents))
+        return changes
+
+
+def rename_in_module(occurrences_finder, new_name, resource=None, pymodule=None,
+                     replace_primary=False, region=None, reads=True, writes=True):
+    """Returns the changed source or `None` if there is no changes"""
+    if resource is not None:
+        source_code = resource.read()
+    else:
+        source_code = pymodule.source_code
+    change_collector = codeanalyze.ChangeCollector(source_code)
+    for occurrence in occurrences_finder.find_occurrences(resource, pymodule):
+        if replace_primary and occurrence.is_a_fixed_primary():
+            continue
+        if replace_primary:
+            start, end = occurrence.get_primary_range()
+        else:
+            start, end = occurrence.get_word_range()
+        if (not reads and not occurrence.is_written()) or \
+           (not writes and occurrence.is_written()):
+            continue
+        if region is None or region[0] <= start < region[1]:
+            change_collector.add_change(start, end, new_name)
+    return change_collector.get_changed()
+
+def _is_local(pyname):
+    module, lineno = pyname.get_definition_location()
+    if lineno is None:
+        return False
+    scope = module.get_scope().get_inner_scope_for_line(lineno)
+    if isinstance(pyname, pynames.DefinedName) and \
+       scope.get_kind() in ('Function', 'Class'):
+        scope = scope.parent
+    return scope.get_kind() == 'Function' and \
+           pyname in scope.get_names().values() and \
+           isinstance(pyname, pynames.AssignedName)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/restructure.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,307 @@
+import warnings
+
+from rope.base import change, taskhandle, builtins, ast, codeanalyze
+from rope.refactor import patchedast, similarfinder, sourceutils
+from rope.refactor.importutils import module_imports
+
+
+class Restructure(object):
+    """A class to perform python restructurings
+
+    A restructuring transforms pieces of code matching `pattern` to
+    `goal`.  In the `pattern` wildcards can appear.  Wildcards match
+    some piece of code based on their kind and arguments that are
+    passed to them through `args`.
+
+    `args` is a dictionary of wildcard names to wildcard arguments.
+    If the argument is a tuple, the first item of the tuple is
+    considered to be the name of the wildcard to use; otherwise the
+    "default" wildcard is used.  For getting the list arguments a
+    wildcard supports, see the pydoc of the wildcard.  (see
+    `rope.refactor.wildcard.DefaultWildcard` for the default
+    wildcard.)
+
+    `wildcards` is the list of wildcard types that can appear in
+    `pattern`.  See `rope.refactor.wildcards`.  If a wildcard does not
+    specify its kind (by using a tuple in args), the wildcard named
+    "default" is used.  So there should be a wildcard with "default"
+    name in `wildcards`.
+
+    `imports` is the list of imports that changed modules should
+    import.  Note that rope handles duplicate imports and does not add
+    the import if it already appears.
+
+    Example #1::
+
+      pattern ${pyobject}.get_attribute(${name})
+      goal ${pyobject}[${name}]
+      args pyobject: instance=rope.base.pyobjects.PyObject
+
+    Example #2::
+
+      pattern ${name} in ${pyobject}.get_attributes()
+      goal ${name} in {pyobject}
+      args pyobject: instance=rope.base.pyobjects.PyObject
+
+    Example #3::
+
+      pattern ${pycore}.create_module(${project}.root, ${name})
+      goal generate.create_module(${project}, ${name})
+
+      imports
+       from rope.contrib import generate
+
+      args
+       pycore: type=rope.base.pycore.PyCore
+       project: type=rope.base.project.Project
+
+    Example #4::
+
+      pattern ${pow}(${param1}, ${param2})
+      goal ${param1} ** ${param2}
+      args pow: name=mod.pow, exact
+
+    Example #5::
+
+      pattern ${inst}.longtask(${p1}, ${p2})
+      goal
+       ${inst}.subtask1(${p1})
+       ${inst}.subtask2(${p2})
+      args
+       inst: type=mod.A,unsure
+
+    """
+
+    def __init__(self, project, pattern, goal, args=None,
+                 imports=None, wildcards=None):
+        """Construct a restructuring
+
+        See class pydoc for more info about the arguments.
+
+        """
+        self.pycore = project.pycore
+        self.pattern = pattern
+        self.goal = goal
+        self.args = args
+        if self.args is None:
+            self.args = {}
+        self.imports = imports
+        if self.imports is None:
+            self.imports = []
+        self.wildcards = wildcards
+        self.template = similarfinder.CodeTemplate(self.goal)
+
+    def get_changes(self, checks=None, imports=None, resources=None,
+                    task_handle=taskhandle.NullTaskHandle()):
+        """Get the changes needed by this restructuring
+
+        `resources` can be a list of `rope.base.resources.File`\s to
+        apply the restructuring on.  If `None`, the restructuring will
+        be applied to all python files.
+
+        `checks` argument has been deprecated.  Use the `args` argument
+        of the constructor.  The usage of::
+
+          strchecks = {'obj1.type': 'mod.A', 'obj2': 'mod.B',
+                       'obj3.object': 'mod.C'}
+          checks = restructuring.make_checks(strchecks)
+
+        can be replaced with::
+
+          args = {'obj1': 'type=mod.A', 'obj2': 'name=mod.B',
+                  'obj3': 'object=mod.C'}
+
+        where obj1, obj2 and obj3 are wildcard names that appear
+        in restructuring pattern.
+
+        """
+        if checks is not None:
+            warnings.warn(
+                'The use of checks parameter is deprecated; '
+                'use the args parameter of the constructor instead.',
+                DeprecationWarning, stacklevel=2)
+            for name, value in checks.items():
+                self.args[name] = similarfinder._pydefined_to_str(value)
+        if imports is not None:
+            warnings.warn(
+                'The use of imports parameter is deprecated; '
+                'use imports parameter of the constructor, instead.',
+                DeprecationWarning, stacklevel=2)
+            self.imports = imports
+        changes = change.ChangeSet('Restructuring <%s> to <%s>' %
+                                   (self.pattern, self.goal))
+        if resources is not None:
+            files = [resource for resource in resources
+                     if self.pycore.is_python_file(resource)]
+        else:
+            files = self.pycore.get_python_files()
+        job_set = task_handle.create_jobset('Collecting Changes', len(files))
+        for resource in files:
+            job_set.started_job(resource.path)
+            pymodule = self.pycore.resource_to_pyobject(resource)
+            finder = similarfinder.SimilarFinder(pymodule,
+                                                 wildcards=self.wildcards)
+            matches = list(finder.get_matches(self.pattern, self.args))
+            computer = self._compute_changes(matches, pymodule)
+            result = computer.get_changed()
+            if result is not None:
+                imported_source = self._add_imports(resource, result,
+                                                    self.imports)
+                changes.add_change(change.ChangeContents(resource,
+                                                         imported_source))
+            job_set.finished_job()
+        return changes
+
+    def _compute_changes(self, matches, pymodule):
+        return _ChangeComputer(
+            pymodule.source_code, pymodule.get_ast(),
+            pymodule.lines, self.template, matches)
+
+    def _add_imports(self, resource, source, imports):
+        if not imports:
+            return source
+        import_infos = self._get_import_infos(resource, imports)
+        pymodule = self.pycore.get_string_module(source, resource)
+        imports = module_imports.ModuleImports(self.pycore, pymodule)
+        for import_info in import_infos:
+            imports.add_import(import_info)
+        return imports.get_changed_source()
+
+    def _get_import_infos(self, resource, imports):
+        pymodule = self.pycore.get_string_module('\n'.join(imports),
+                                                 resource)
+        imports = module_imports.ModuleImports(self.pycore, pymodule)
+        return [imports.import_info
+                for imports in imports.imports]
+
+    def make_checks(self, string_checks):
+        """Convert str to str dicts to str to PyObject dicts
+
+        This function is here to ease writing a UI.
+
+        """
+        checks = {}
+        for key, value in string_checks.items():
+            is_pyname = not key.endswith('.object') and \
+                        not key.endswith('.type')
+            evaluated = self._evaluate(value, is_pyname=is_pyname)
+            if evaluated is not None:
+                checks[key] = evaluated
+        return checks
+
+    def _evaluate(self, code, is_pyname=True):
+        attributes = code.split('.')
+        pyname = None
+        if attributes[0] in ('__builtin__', '__builtins__'):
+            class _BuiltinsStub(object):
+                def get_attribute(self, name):
+                    return builtins.builtins[name]
+            pyobject = _BuiltinsStub()
+        else:
+            pyobject = self.pycore.get_module(attributes[0])
+        for attribute in attributes[1:]:
+            pyname = pyobject[attribute]
+            if pyname is None:
+                return None
+            pyobject = pyname.get_object()
+        return pyname if is_pyname else pyobject
+
+
+def replace(code, pattern, goal):
+    """used by other refactorings"""
+    finder = similarfinder.RawSimilarFinder(code)
+    matches = list(finder.get_matches(pattern))
+    ast = patchedast.get_patched_ast(code)
+    lines = codeanalyze.SourceLinesAdapter(code)
+    template = similarfinder.CodeTemplate(goal)
+    computer = _ChangeComputer(code, ast, lines, template, matches)
+    result = computer.get_changed()
+    if result is None:
+        return code
+    return result
+
+
+class _ChangeComputer(object):
+
+    def __init__(self, code, ast, lines, goal, matches):
+        self.source = code
+        self.goal = goal
+        self.matches = matches
+        self.ast = ast
+        self.lines = lines
+        self.matched_asts = {}
+        self._nearest_roots = {}
+        if self._is_expression():
+            for match in self.matches:
+                self.matched_asts[match.ast] = match
+
+    def get_changed(self):
+        if self._is_expression():
+            result = self._get_node_text(self.ast)
+            if result == self.source:
+                return None
+            return result
+        else:
+            collector = codeanalyze.ChangeCollector(self.source)
+            last_end = -1
+            for match in self.matches:
+                start, end = match.get_region()
+                if start < last_end:
+                    if not self._is_expression():
+                        continue
+                last_end = end
+                replacement = self._get_matched_text(match)
+                collector.add_change(start, end, replacement)
+            return collector.get_changed()
+
+    def _is_expression(self):
+        return self.matches and isinstance(self.matches[0],
+                                           similarfinder.ExpressionMatch)
+
+    def _get_matched_text(self, match):
+        mapping = {}
+        for name in self.goal.get_names():
+            node = match.get_ast(name)
+            if node is None:
+                raise similarfinder.BadNameInCheckError(
+                    'Unknown name <%s>' % name)
+            force = self._is_expression() and match.ast == node
+            mapping[name] = self._get_node_text(node, force)
+        unindented = self.goal.substitute(mapping)
+        return self._auto_indent(match.get_region()[0], unindented)
+
+    def _get_node_text(self, node, force=False):
+        if not force and node in self.matched_asts:
+            return self._get_matched_text(self.matched_asts[node])
+        start, end = patchedast.node_region(node)
+        main_text = self.source[start:end]
+        collector = codeanalyze.ChangeCollector(main_text)
+        for node in self._get_nearest_roots(node):
+            sub_start, sub_end = patchedast.node_region(node)
+            collector.add_change(sub_start - start, sub_end - start,
+                                 self._get_node_text(node))
+        result = collector.get_changed()
+        if result is None:
+            return main_text
+        return result
+
+    def _auto_indent(self, offset, text):
+        lineno = self.lines.get_line_number(offset)
+        indents = sourceutils.get_indents(self.lines, lineno)
+        result = []
+        for index, line in enumerate(text.splitlines(True)):
+            if index != 0 and line.strip():
+                result.append(' ' * indents)
+            result.append(line)
+        return ''.join(result)
+
+    def _get_nearest_roots(self, node):
+        if node not in self._nearest_roots:
+            result = []
+            for child in ast.get_child_nodes(node):
+                if child in self.matched_asts:
+                    result.append(child)
+                else:
+                    result.extend(self._get_nearest_roots(child))
+            self._nearest_roots[node] = result
+        return self._nearest_roots[node]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/similarfinder.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,362 @@
+"""This module can be used for finding similar code"""
+import re
+
+import rope.refactor.wildcards
+from rope.base import codeanalyze, evaluate, exceptions, ast, builtins
+from rope.refactor import (patchedast, sourceutils, occurrences,
+                           wildcards, importutils)
+
+
+class BadNameInCheckError(exceptions.RefactoringError):
+    pass
+
+
+class SimilarFinder(object):
+    """`SimilarFinder` can be used to find similar pieces of code
+
+    See the notes in the `rope.refactor.restructure` module for more
+    info.
+
+    """
+
+    def __init__(self, pymodule, wildcards=None):
+        """Construct a SimilarFinder"""
+        self.source = pymodule.source_code
+        self.raw_finder = RawSimilarFinder(
+            pymodule.source_code, pymodule.get_ast(), self._does_match)
+        self.pymodule = pymodule
+        if wildcards is None:
+            self.wildcards = {}
+            for wildcard in [rope.refactor.wildcards.
+                             DefaultWildcard(pymodule.pycore.project)]:
+                self.wildcards[wildcard.get_name()] = wildcard
+        else:
+            self.wildcards = wildcards
+
+    def get_matches(self, code, args={}, start=0, end=None):
+        self.args = args
+        if end is None:
+            end = len(self.source)
+        skip_region = None
+        if 'skip' in args.get('', {}):
+            resource, region = args['']['skip']
+            if resource == self.pymodule.get_resource():
+                skip_region = region            
+        return self.raw_finder.get_matches(code, start=start, end=end,
+                                           skip=skip_region)
+
+    def get_match_regions(self, *args, **kwds):
+        for match in self.get_matches(*args, **kwds):
+            yield match.get_region()
+
+    def _does_match(self, node, name):
+        arg = self.args.get(name, '')
+        kind = 'default'
+        if isinstance(arg, (tuple, list)):
+            kind = arg[0]
+            arg = arg[1]
+        suspect = wildcards.Suspect(self.pymodule, node, name)
+        return self.wildcards[kind].matches(suspect, arg)
+
+
+class RawSimilarFinder(object):
+    """A class for finding similar expressions and statements"""
+
+    def __init__(self, source, node=None, does_match=None):
+        if node is None:
+            node = ast.parse(source)
+        if does_match is None:
+            self.does_match = self._simple_does_match
+        else:
+            self.does_match = does_match
+        self._init_using_ast(node, source)
+
+    def _simple_does_match(self, node, name):
+        return isinstance(node, (ast.expr, ast.Name))
+
+    def _init_using_ast(self, node, source):
+        self.source = source
+        self._matched_asts = {}
+        if not hasattr(node, 'region'):
+            patchedast.patch_ast(node, source)
+        self.ast = node
+
+    def get_matches(self, code, start=0, end=None, skip=None):
+        """Search for `code` in source and return a list of `Match`\es
+
+        `code` can contain wildcards.  ``${name}`` matches normal
+        names and ``${?name} can match any expression.  You can use
+        `Match.get_ast()` for getting the node that has matched a
+        given pattern.
+
+        """
+        if end is None:
+            end = len(self.source)
+        for match in self._get_matched_asts(code):
+            match_start, match_end = match.get_region()
+            if start <= match_start and match_end <= end:
+                if skip is not None and (skip[0] < match_end and
+                                         skip[1] > match_start):
+                    continue                    
+                yield match
+
+    def _get_matched_asts(self, code):
+        if code not in self._matched_asts:
+            wanted = self._create_pattern(code)
+            matches = _ASTMatcher(self.ast, wanted,
+                                  self.does_match).find_matches()
+            self._matched_asts[code] = matches
+        return self._matched_asts[code]
+
+    def _create_pattern(self, expression):
+        expression = self._replace_wildcards(expression)
+        node = ast.parse(expression)
+        # Getting Module.Stmt.nodes
+        nodes = node.body
+        if len(nodes) == 1 and isinstance(nodes[0], ast.Expr):
+            # Getting Discard.expr
+            wanted = nodes[0].value
+        else:
+            wanted = nodes
+        return wanted
+
+    def _replace_wildcards(self, expression):
+        ropevar = _RopeVariable()
+        template = CodeTemplate(expression)
+        mapping = {}
+        for name in template.get_names():
+            mapping[name] = ropevar.get_var(name)
+        return template.substitute(mapping)
+
+
+class _ASTMatcher(object):
+
+    def __init__(self, body, pattern, does_match):
+        """Searches the given pattern in the body AST.
+
+        body is an AST node and pattern can be either an AST node or
+        a list of ASTs nodes
+        """
+        self.body = body
+        self.pattern = pattern
+        self.matches = None
+        self.ropevar = _RopeVariable()
+        self.matches_callback = does_match
+
+    def find_matches(self):
+        if self.matches is None:
+            self.matches = []
+            ast.call_for_nodes(self.body, self._check_node, recursive=True)
+        return self.matches
+
+    def _check_node(self, node):
+        if isinstance(self.pattern, list):
+            self._check_statements(node)
+        else:
+            self._check_expression(node)
+
+    def _check_expression(self, node):
+        mapping = {}
+        if self._match_nodes(self.pattern, node, mapping):
+            self.matches.append(ExpressionMatch(node, mapping))
+
+    def _check_statements(self, node):
+        for child in ast.get_children(node):
+            if isinstance(child, (list, tuple)):
+                self.__check_stmt_list(child)
+
+    def __check_stmt_list(self, nodes):
+        for index in range(len(nodes)):
+            if len(nodes) - index >= len(self.pattern):
+                current_stmts = nodes[index:index + len(self.pattern)]
+                mapping = {}
+                if self._match_stmts(current_stmts, mapping):
+                    self.matches.append(StatementMatch(current_stmts, mapping))
+
+    def _match_nodes(self, expected, node, mapping):
+        if isinstance(expected, ast.Name):
+           if self.ropevar.is_var(expected.id):
+               return self._match_wildcard(expected, node, mapping)
+        if not isinstance(expected, ast.AST):
+            return expected == node
+        if expected.__class__ != node.__class__:
+            return False
+
+        children1 = self._get_children(expected)
+        children2 = self._get_children(node)
+        if len(children1) != len(children2):
+            return False
+        for child1, child2 in zip(children1, children2):
+            if isinstance(child1, ast.AST):
+                if not self._match_nodes(child1, child2, mapping):
+                    return False
+            elif isinstance(child1, (list, tuple)):
+                if not isinstance(child2, (list, tuple)) or \
+                   len(child1) != len(child2):
+                    return False
+                for c1, c2 in zip(child1, child2):
+                    if not self._match_nodes(c1, c2, mapping):
+                        return False
+            else:
+                if child1 != child2:
+                    return False
+        return True
+
+    def _get_children(self, node):
+        """Return not `ast.expr_context` children of `node`"""
+        children = ast.get_children(node)
+        return [child for child in children
+                if not isinstance(child, ast.expr_context)]
+
+    def _match_stmts(self, current_stmts, mapping):
+        if len(current_stmts) != len(self.pattern):
+            return False
+        for stmt, expected in zip(current_stmts, self.pattern):
+            if not self._match_nodes(expected, stmt, mapping):
+                return False
+        return True
+
+    def _match_wildcard(self, node1, node2, mapping):
+        name = self.ropevar.get_base(node1.id)
+        if name not in mapping:
+            if self.matches_callback(node2, name):
+                mapping[name] = node2
+                return True
+            return False
+        else:
+            return self._match_nodes(mapping[name], node2, {})
+
+
+class Match(object):
+
+    def __init__(self, mapping):
+        self.mapping = mapping
+
+    def get_region(self):
+        """Returns match region"""
+
+    def get_ast(self, name):
+        """Return the ast node that has matched rope variables"""
+        return self.mapping.get(name, None)
+
+
+class ExpressionMatch(Match):
+
+    def __init__(self, ast, mapping):
+        super(ExpressionMatch, self).__init__(mapping)
+        self.ast = ast
+
+    def get_region(self):
+        return self.ast.region
+
+
+class StatementMatch(Match):
+
+    def __init__(self, ast_list, mapping):
+        super(StatementMatch, self).__init__(mapping)
+        self.ast_list = ast_list
+
+    def get_region(self):
+        return self.ast_list[0].region[0], self.ast_list[-1].region[1]
+
+
+class CodeTemplate(object):
+
+    def __init__(self, template):
+        self.template = template
+        self._find_names()
+
+    def _find_names(self):
+        self.names = {}
+        for match in CodeTemplate._get_pattern().finditer(self.template):
+            if 'name' in match.groupdict() and \
+               match.group('name') is not None:
+                start, end = match.span('name')
+                name = self.template[start + 2:end - 1]
+                if name not in self.names:
+                    self.names[name] = []
+                self.names[name].append((start, end))
+
+    def get_names(self):
+        return self.names.keys()
+
+    def substitute(self, mapping):
+        collector = codeanalyze.ChangeCollector(self.template)
+        for name, occurrences in self.names.items():
+            for region in occurrences:
+                collector.add_change(region[0], region[1], mapping[name])
+        result = collector.get_changed()
+        if result is None:
+            return self.template
+        return result
+
+    _match_pattern = None
+
+    @classmethod
+    def _get_pattern(cls):
+        if cls._match_pattern is None:
+            pattern = codeanalyze.get_comment_pattern() + '|' + \
+                      codeanalyze.get_string_pattern() + '|' + \
+                      r'(?P<name>\$\{[^\s\$\}]*\})'
+            cls._match_pattern = re.compile(pattern)
+        return cls._match_pattern
+
+
+class _RopeVariable(object):
+    """Transform and identify rope inserted wildcards"""
+
+    _normal_prefix = '__rope__variable_normal_'
+    _any_prefix = '__rope__variable_any_'
+
+    def get_var(self, name):
+        if name.startswith('?'):
+            return self._get_any(name)
+        else:
+            return self._get_normal(name)
+
+    def is_var(self, name):
+        return self._is_normal(name) or self._is_var(name)
+
+    def get_base(self, name):
+        if self._is_normal(name):
+            return name[len(self._normal_prefix):]
+        if self._is_var(name):
+            return '?' + name[len(self._any_prefix):]
+
+    def _get_normal(self, name):
+        return self._normal_prefix + name
+
+    def _get_any(self, name):
+        return self._any_prefix + name[1:]
+
+    def _is_normal(self, name):
+        return name.startswith(self._normal_prefix)
+
+    def _is_var(self, name):
+        return name.startswith(self._any_prefix)
+
+
+def make_pattern(code, variables):
+    variables = set(variables)
+    collector = codeanalyze.ChangeCollector(code)
+    def does_match(node, name):
+        return isinstance(node, ast.Name) and node.id == name
+    finder = RawSimilarFinder(code, does_match=does_match)
+    for variable in variables:
+        for match in finder.get_matches('${%s}' % variable):
+            start, end = match.get_region()
+            collector.add_change(start, end, '${%s}' % variable)
+    result = collector.get_changed()
+    return result if result is not None else code
+
+
+def _pydefined_to_str(pydefined):
+    address = []
+    if isinstance(pydefined, (builtins.BuiltinClass, builtins.BuiltinFunction)):
+        return '__builtins__.' + pydefined.get_name()
+    else:
+        while pydefined.parent is not None:
+            address.insert(0, pydefined.get_name())
+            pydefined = pydefined.parent
+        module_name = pydefined.pycore.modname(pydefined.resource)
+    return '.'.join(module_name.split('.') + address)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/sourceutils.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,92 @@
+from rope.base import ast, codeanalyze
+
+
+def get_indents(lines, lineno):
+    return codeanalyze.count_line_indents(lines.get_line(lineno))
+
+
+def find_minimum_indents(source_code):
+    result = 80
+    lines = source_code.split('\n')
+    for line in lines:
+        if line.strip() == '':
+            continue
+        result = min(result, codeanalyze.count_line_indents(line))
+    return result
+
+
+def indent_lines(source_code, amount):
+    if amount == 0:
+        return source_code
+    lines = source_code.splitlines(True)
+    result = []
+    for l in lines:
+        if l.strip() == '':
+            result.append('\n')
+            continue
+        if amount < 0:
+            indents = codeanalyze.count_line_indents(l)
+            result.append(max(0, indents + amount) * ' ' + l.lstrip())
+        else:
+            result.append(' ' * amount + l)
+    return ''.join(result)
+
+
+def fix_indentation(code, new_indents):
+    """Change the indentation of `code` to `new_indents`"""
+    min_indents = find_minimum_indents(code)
+    return indent_lines(code, new_indents - min_indents)
+
+
+def add_methods(pymodule, class_scope, methods_sources):
+    source_code = pymodule.source_code
+    lines = pymodule.lines
+    insertion_line = class_scope.get_end()
+    if class_scope.get_scopes():
+        insertion_line = class_scope.get_scopes()[-1].get_end()
+    insertion_offset = lines.get_line_end(insertion_line)
+    methods = '\n\n' + '\n\n'.join(methods_sources)
+    indented_methods = fix_indentation(
+        methods, get_indents(lines, class_scope.get_start()) +
+        get_indent(pymodule.pycore))
+    result = []
+    result.append(source_code[:insertion_offset])
+    result.append(indented_methods)
+    result.append(source_code[insertion_offset:])
+    return ''.join(result)
+
+
+def get_body(pyfunction):
+    """Return unindented function body"""
+    scope = pyfunction.get_scope()
+    pymodule = pyfunction.get_module()
+    start, end = get_body_region(pyfunction)
+    return fix_indentation(pymodule.source_code[start:end], 0)
+
+
+def get_body_region(defined):
+    """Return the start and end offsets of function body"""
+    scope = defined.get_scope()
+    pymodule = defined.get_module()
+    lines = pymodule.lines
+    node = defined.get_ast()
+    start_line = node.lineno
+    if defined.get_doc() is None:
+        start_line = node.body[0].lineno
+    elif len(node.body) > 1:
+        start_line = node.body[1].lineno
+    start = lines.get_line_start(start_line)
+    scope_start = pymodule.logical_lines.logical_line_in(scope.start)
+    if scope_start[1] >= start_line:
+        # a one-liner!
+        # XXX: what if colon appears in a string
+        start = pymodule.source_code.index(':', start) + 1
+        while pymodule.source_code[start].isspace():
+            start += 1
+    end = min(lines.get_line_end(scope.end) + 1, len(pymodule.source_code))
+    return start, end
+
+
+def get_indent(pycore):
+    project = pycore.project
+    return project.prefs.get('indent_size', 4)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/suites.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,142 @@
+from rope.base import ast
+
+
+def find_visible(node, lines):
+    """Return the line which is visible from all `lines`"""
+    root = ast_suite_tree(node)
+    return find_visible_for_suite(root, lines)
+
+
+def find_visible_for_suite(root, lines):
+    if len(lines) == 1:
+        return lines[0]
+    line1 = lines[0]
+    line2 = find_visible_for_suite(root, lines[1:])
+    suite1 = root.find_suite(line1)
+    suite2 = root.find_suite(line2)
+    def valid(suite):
+        return suite is not None and not suite.ignored
+    if valid(suite1) and not valid(suite2):
+        return line1
+    if not valid(suite1) and valid(suite2):
+        return line2
+    if not valid(suite1) and not valid(suite2):
+        return None
+    while suite1 != suite2 and suite1.parent != suite2.parent:
+        if suite1._get_level() < suite2._get_level():
+            line2 = suite2.get_start()
+            suite2 = suite2.parent
+        elif suite1._get_level() > suite2._get_level():
+            line1 = suite1.get_start()
+            suite1 = suite1.parent
+        else:
+            line1 = suite1.get_start()
+            line2 = suite2.get_start()
+            suite1 = suite1.parent
+            suite2 = suite2.parent
+    if suite1 == suite2:
+        return min(line1, line2)
+    return min(suite1.get_start(), suite2.get_start())
+
+
+def ast_suite_tree(node):
+    if hasattr(node, 'lineno'):
+        lineno = node.lineno
+    else:
+        lineno = 1
+    return Suite(node.body, lineno)
+
+
+class Suite(object):
+
+    def __init__(self, child_nodes, lineno, parent=None, ignored=False):
+        self.parent = parent
+        self.lineno = lineno
+        self.child_nodes = child_nodes
+        self._children = None
+        self.ignored = ignored
+
+    def get_start(self):
+        if self.parent is None:
+            if self.child_nodes:
+                return self.local_start()
+            else:
+                return 1
+        return self.lineno
+
+    def get_children(self):
+        if self._children is None:
+            walker = _SuiteWalker(self)
+            for child in self.child_nodes:
+                ast.walk(child, walker)
+            self._children = walker.suites
+        return self._children
+
+    def local_start(self):
+        return self.child_nodes[0].lineno
+
+    def local_end(self):
+        end = self.child_nodes[-1].lineno
+        if self.get_children():
+            end = max(end, self.get_children()[-1].local_end())
+        return end
+
+    def find_suite(self, line):
+        if line is None:
+            return None
+        for child in self.get_children():
+            if child.local_start() <= line <= child.local_end():
+                return child.find_suite(line)
+        return self
+
+    def _get_level(self):
+        if self.parent is None:
+            return 0
+        return self.parent._get_level() + 1
+
+
+class _SuiteWalker(object):
+
+    def __init__(self, suite):
+        self.suite = suite
+        self.suites = []
+
+    def _If(self, node):
+        self._add_if_like_node(node)
+
+    def _For(self, node):
+        self._add_if_like_node(node)
+
+    def _While(self, node):
+        self._add_if_like_node(node)
+
+    def _With(self, node):
+        self.suites.append(Suite(node.body, node.lineno, self.suite))
+
+    def _TryFinally(self, node):
+        if len(node.finalbody) == 1 and \
+           isinstance(node.body[0], ast.TryExcept):
+            self._TryExcept(node.body[0])
+        else:
+            self.suites.append(Suite(node.body, node.lineno, self.suite))
+        self.suites.append(Suite(node.finalbody, node.lineno, self.suite))
+
+    def _TryExcept(self, node):
+        self.suites.append(Suite(node.body, node.lineno, self.suite))
+        for handler in node.handlers:
+            self.suites.append(Suite(handler.body, node.lineno, self.suite))
+        if node.orelse:
+            self.suites.append(Suite(node.orelse, node.lineno, self.suite))
+
+    def _add_if_like_node(self, node):
+        self.suites.append(Suite(node.body, node.lineno, self.suite))
+        if node.orelse:
+            self.suites.append(Suite(node.orelse, node.lineno, self.suite))
+
+    def _FunctionDef(self, node):
+        self.suites.append(Suite(node.body, node.lineno,
+                                 self.suite, ignored=True))
+
+    def _ClassDef(self, node):
+        self.suites.append(Suite(node.body, node.lineno,
+                                 self.suite, ignored=True))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/topackage.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,32 @@
+import rope.refactor.importutils
+from rope.base.change import ChangeSet, ChangeContents, MoveResource, CreateFolder
+
+
+class ModuleToPackage(object):
+
+    def __init__(self, project, resource):
+        self.project = project
+        self.pycore = project.pycore
+        self.resource = resource
+
+    def get_changes(self):
+        changes = ChangeSet('Transform <%s> module to package' %
+                            self.resource.path)
+        new_content = self._transform_relatives_to_absolute(self.resource)
+        if new_content is not None:
+            changes.add_change(ChangeContents(self.resource, new_content))
+        parent = self.resource.parent
+        name = self.resource.name[:-3]
+        changes.add_change(CreateFolder(parent, name))
+        parent_path = parent.path + '/'
+        if not parent.path:
+            parent_path = ''
+        new_path = parent_path + '%s/__init__.py' % name
+        if self.resource.project == self.project:
+            changes.add_change(MoveResource(self.resource, new_path))
+        return changes
+
+    def _transform_relatives_to_absolute(self, resource):
+        pymodule = self.pycore.resource_to_pyobject(resource)
+        import_tools = rope.refactor.importutils.ImportTools(self.pycore)
+        return import_tools.relatives_to_absolutes(pymodule)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/usefunction.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,171 @@
+from rope.base import (change, taskhandle, evaluate,
+                       exceptions, pyobjects, pynames, ast)
+from rope.refactor import restructure, sourceutils, similarfinder, importutils
+
+
+class UseFunction(object):
+    """Try to use a function wherever possible"""
+
+    def __init__(self, project, resource, offset):
+        self.project = project
+        self.offset = offset
+        this_pymodule = project.pycore.resource_to_pyobject(resource)
+        pyname = evaluate.eval_location(this_pymodule, offset)
+        if pyname is None:
+            raise exceptions.RefactoringError('Unresolvable name selected')
+        self.pyfunction = pyname.get_object()
+        if not isinstance(self.pyfunction, pyobjects.PyFunction) or \
+           not isinstance(self.pyfunction.parent, pyobjects.PyModule):
+            raise exceptions.RefactoringError(
+                'Use function works for global functions, only.')
+        self.resource = self.pyfunction.get_module().get_resource()
+        self._check_returns()
+
+    def _check_returns(self):
+        node = self.pyfunction.get_ast()
+        if _yield_count(node):
+            raise exceptions.RefactoringError('Use function should not '
+                                              'be used on generators.')
+        returns = _return_count(node)
+        if returns > 1:
+            raise exceptions.RefactoringError('usefunction: Function has more '
+                                              'than one return statement.')
+        if returns == 1 and not _returns_last(node):
+            raise exceptions.RefactoringError('usefunction: return should '
+                                              'be the last statement.')
+
+    def get_changes(self, resources=None,
+                    task_handle=taskhandle.NullTaskHandle()):
+        if resources is None:
+            resources = self.project.pycore.get_python_files()
+        changes = change.ChangeSet('Using function <%s>' %
+                                   self.pyfunction.get_name())
+        if self.resource in resources:
+            newresources = list(resources)
+            newresources.remove(self.resource)
+        for c in self._restructure(newresources, task_handle).changes:
+            changes.add_change(c)
+        if self.resource in resources:
+            for c in self._restructure([self.resource], task_handle,
+                                       others=False).changes:
+                changes.add_change(c)
+        return changes
+
+    def get_function_name(self):
+        return self.pyfunction.get_name()
+
+    def _restructure(self, resources, task_handle, others=True):
+        body = self._get_body()
+        pattern = self._make_pattern()
+        goal = self._make_goal(import_=others)
+        imports = None
+        if others:
+            imports = ['import %s' % self._module_name()]
+
+        body_region = sourceutils.get_body_region(self.pyfunction)
+        args_value = {'skip': (self.resource, body_region)}
+        args = {'': args_value}
+
+        restructuring = restructure.Restructure(
+            self.project, pattern, goal, args=args, imports=imports)
+        return restructuring.get_changes(resources=resources,
+                                         task_handle=task_handle)
+
+    def _find_temps(self):
+        return find_temps(self.project, self._get_body())
+
+    def _module_name(self):
+        return self.project.pycore.modname(self.resource)
+
+    def _make_pattern(self):
+        params = self.pyfunction.get_param_names()
+        body = self._get_body()
+        body = restructure.replace(body, 'return', 'pass')
+        wildcards = list(params)
+        wildcards.extend(self._find_temps())
+        if self._does_return():
+            if self._is_expression():
+                replacement = '${%s}' % self._rope_returned
+            else:
+                replacement = '%s = ${%s}' % (self._rope_result,
+                                              self._rope_returned)
+            body = restructure.replace(
+                body, 'return ${%s}' % self._rope_returned,
+                replacement)
+            wildcards.append(self._rope_result)
+        return similarfinder.make_pattern(body, wildcards)
+
+    def _get_body(self):
+        return sourceutils.get_body(self.pyfunction)
+
+    def _make_goal(self, import_=False):
+        params = self.pyfunction.get_param_names()
+        function_name = self.pyfunction.get_name()
+        if import_:
+            function_name = self._module_name() + '.' + function_name
+        goal = '%s(%s)' % (function_name,
+                           ', ' .join(('${%s}' % p) for p in params))
+        if self._does_return() and not self._is_expression():
+            goal = '${%s} = %s' % (self._rope_result, goal)
+        return goal
+
+    def _does_return(self):
+        body = self._get_body()
+        removed_return = restructure.replace(body, 'return ${result}', '')
+        return removed_return != body
+
+    def _is_expression(self):
+        return len(self.pyfunction.get_ast().body) == 1
+
+    _rope_result = '_rope__result'
+    _rope_returned = '_rope__returned'
+
+
+def find_temps(project, code):
+    code = 'def f():\n' + sourceutils.indent_lines(code, 4)
+    pymodule = project.pycore.get_string_module(code)
+    result = []
+    function_scope = pymodule.get_scope().get_scopes()[0]
+    for name, pyname in function_scope.get_names().items():
+        if isinstance(pyname, pynames.AssignedName):
+            result.append(name)
+    return result
+
+
+def _returns_last(node):
+    return node.body and isinstance(node.body[-1], ast.Return)
+
+def _yield_count(node):
+    visitor = _ReturnOrYieldFinder()
+    visitor.start_walking(node)
+    return visitor.yields
+
+def _return_count(node):
+    visitor = _ReturnOrYieldFinder()
+    visitor.start_walking(node)
+    return visitor.returns
+
+class _ReturnOrYieldFinder(object):
+
+    def __init__(self):
+        self.returns = 0
+        self.yields = 0
+
+    def _Return(self, node):
+        self.returns += 1
+
+    def _Yield(self, node):
+        self.yields += 1
+
+    def _FunctionDef(self, node):
+        pass
+
+    def _ClassDef(self, node):
+        pass
+
+    def start_walking(self, node):
+        nodes = [node]
+        if isinstance(node, ast.FunctionDef):
+            nodes = ast.get_child_nodes(node)
+        for child in nodes:
+            ast.walk(child, self)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/rope/refactor/wildcards.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,176 @@
+from rope.base import ast, evaluate, builtins, pyobjects
+from rope.refactor import patchedast, occurrences
+
+
+class Wildcard(object):
+
+    def get_name(self):
+        """Return the name of this wildcard"""
+
+    def matches(self, suspect, arg):
+        """Return `True` if `suspect` matches this wildcard"""
+
+
+class Suspect(object):
+
+    def __init__(self, pymodule, node, name):
+        self.name = name
+        self.pymodule = pymodule
+        self.node = node
+
+
+class DefaultWildcard(object):
+    """The default restructuring wildcard
+
+    The argument passed to this wildcard is in the
+    ``key1=value1,key2=value2,...`` format.  Possible keys are:
+
+    * name - for checking the reference
+    * type - for checking the type
+    * object - for checking the object
+    * instance - for checking types but similar to builtin isinstance
+    * exact - matching only occurrences with the same name as the wildcard
+    * unsure - matching unsure occurrences
+
+    """
+
+    def __init__(self, project):
+        self.project = project
+
+    def get_name(self):
+        return 'default'
+
+    def matches(self, suspect, arg=''):
+        args = parse_arg(arg)
+
+        if not self._check_exact(args, suspect):
+            return False
+        if not self._check_object(args, suspect):
+            return False
+        return True
+
+    def _check_object(self, args, suspect):
+        kind = None
+        expected = None
+        unsure = args.get('unsure', False)
+        for check in ['name', 'object', 'type', 'instance']:
+            if check in args:
+                kind = check
+                expected = args[check]
+            if expected is not None:
+                checker = _CheckObject(self.project, expected,
+                                       kind, unsure=unsure)
+                return checker(suspect.pymodule, suspect.node)
+        return True
+
+    def _check_exact(self, args, suspect):
+        node = suspect.node
+        if args.get('exact'):
+            if not isinstance(node, ast.Name) or not node.id == suspect.name:
+                return False
+        else:
+            if not isinstance(node, ast.expr):
+                return False
+        return True
+
+
+def parse_arg(arg):
+    if isinstance(arg, dict):
+        return arg
+    result = {}
+    tokens = arg.split(',')
+    for token in tokens:
+        if '=' in token:
+            parts = token.split('=', 1)
+            result[parts[0].strip()] = parts[1].strip()
+        else:
+            result[token.strip()] = True
+    return result
+
+
+class _CheckObject(object):
+
+    def __init__(self, project, expected, kind='object', unsure=False):
+        self.project = project
+        self.kind = kind
+        self.unsure = unsure
+        self.expected = self._evaluate(expected)
+
+    def __call__(self, pymodule, node):
+        pyname = self._evaluate_node(pymodule, node)
+        if pyname is None or self.expected is None:
+            return self.unsure
+        if self._unsure_pyname(pyname, unbound=self.kind=='name'):
+            return True
+        if self.kind == 'name':
+            return self._same_pyname(self.expected, pyname)
+        else:
+            pyobject = pyname.get_object()
+            if self.kind == 'object':
+                objects = [pyobject]
+            if self.kind == 'type':
+                objects = [pyobject.get_type()]
+            if self.kind == 'instance':
+                objects = [pyobject]
+                objects.extend(self._get_super_classes(pyobject))
+                objects.extend(self._get_super_classes(pyobject.get_type()))
+            for pyobject in objects:
+                if self._same_pyobject(self.expected.get_object(), pyobject):
+                    return True
+            return False
+
+    def _get_super_classes(self, pyobject):
+        result = []
+        if isinstance(pyobject, pyobjects.AbstractClass):
+            for superclass in pyobject.get_superclasses():
+                result.append(superclass)
+                result.extend(self._get_super_classes(superclass))
+        return result
+
+    def _same_pyobject(self, expected, pyobject):
+        return expected == pyobject
+
+    def _same_pyname(self, expected, pyname):
+        return occurrences.same_pyname(expected, pyname)
+
+    def _unsure_pyname(self, pyname, unbound=True):
+        return self.unsure and occurrences.unsure_pyname(pyname, unbound)
+
+    def _split_name(self, name):
+        parts = name.split('.')
+        expression, kind = parts[0], parts[-1]
+        if len(parts) == 1:
+            kind = 'name'
+        return expression, kind
+
+    def _evaluate_node(self, pymodule, node):
+        scope = pymodule.get_scope().get_inner_scope_for_line(node.lineno)
+        expression = node
+        if isinstance(expression, ast.Name) and \
+           isinstance(expression.ctx, ast.Store):
+            start, end = patchedast.node_region(expression)
+            text = pymodule.source_code[start:end]
+            return evaluate.eval_str(scope, text)
+        else:
+            return evaluate.eval_node(scope, expression)
+
+    def _evaluate(self, code):
+        attributes = code.split('.')
+        pyname = None
+        if attributes[0] in ('__builtin__', '__builtins__'):
+            class _BuiltinsStub(object):
+                def get_attribute(self, name):
+                    return builtins.builtins[name]
+                def __getitem__(self, name):
+                    return builtins.builtins[name]
+                def __contains__(self, name):
+                    return name in builtins.builtins
+            pyobject = _BuiltinsStub()
+        else:
+            pyobject = self.project.pycore.get_module(attributes[0])
+        for attribute in attributes[1:]:
+            pyname = pyobject[attribute]
+            if pyname is None:
+                return None
+            pyobject = pyname.get_object()
+        return pyname
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/__init__.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,36 @@
+import sys
+import unittest
+
+import ropetest.projecttest
+import ropetest.codeanalyzetest
+import ropetest.pycoretest
+import ropetest.pyscopestest
+import ropetest.objectinfertest
+import ropetest.objectdbtest
+import ropetest.advanced_oi_test
+import ropetest.runmodtest
+import ropetest.builtinstest
+import ropetest.historytest
+import ropetest.simplifytest
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(ropetest.projecttest.suite())
+    result.addTests(ropetest.codeanalyzetest.suite())
+    result.addTests(ropetest.pycoretest.suite())
+    result.addTests(ropetest.pyscopestest.suite())
+    result.addTests(ropetest.objectinfertest.suite())
+    result.addTests(ropetest.objectdbtest.suite())
+    result.addTests(ropetest.advanced_oi_test.suite())
+    result.addTests(ropetest.runmodtest.suite())
+    result.addTests(ropetest.builtinstest.suite())
+    result.addTests(ropetest.historytest.suite())
+    result.addTests(ropetest.simplifytest.suite())
+    return result
+
+
+if __name__ == '__main__':
+    runner = unittest.TextTestRunner()
+    result = runner.run(suite())
+    sys.exit(not result.wasSuccessful())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/advanced_oi_test.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,740 @@
+import unittest
+
+import rope.base.oi
+import rope.base.libutils
+from ropetest import testutils
+
+
+class DynamicOITest(unittest.TestCase):
+
+    def setUp(self):
+        super(DynamicOITest, self).setUp()
+        self.project = testutils.sample_project(validate_objectdb=True)
+        self.pycore = self.project.pycore
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(DynamicOITest, self).tearDown()
+
+    def test_simple_dti(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'def a_func(arg):\n    return eval("arg")\n' \
+               'a_var = a_func(a_func)\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        self.assertEquals(pymod['a_func'].get_object(),
+                          pymod['a_var'].get_object())
+
+    def test_module_dti(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        code = 'import mod1\ndef a_func(arg):\n    return eval("arg")\n' \
+               'a_var = a_func(mod1)\n'
+        mod2.write(code)
+        self.pycore.run_module(mod2).wait_process()
+        pymod2 = self.pycore.resource_to_pyobject(mod2)
+        self.assertEquals(self.pycore.resource_to_pyobject(mod1),
+                          pymod2['a_var'].get_object())
+
+    def test_class_from_another_module_dti(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        code1 = 'class AClass(object):\n    pass\n'
+        code2 = 'from mod1 import AClass\n' \
+               '\ndef a_func(arg):\n    return eval("arg")\n' \
+               'a_var = a_func(AClass)\n'
+        mod1.write(code1)
+        mod2.write(code2)
+        self.pycore.run_module(mod2).wait_process()
+        pymod1 = self.pycore.resource_to_pyobject(mod1)
+        pymod2 = self.pycore.resource_to_pyobject(mod2)
+        self.assertEquals(pymod2['AClass'].get_object(),
+                          pymod2['a_var'].get_object())
+
+
+    def test_class_dti(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class AClass(object):\n    pass\n' \
+               '\ndef a_func(arg):\n    return eval("arg")\n' \
+               'a_var = a_func(AClass)\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        self.assertEquals(pymod['AClass'].get_object(),
+                          pymod['a_var'].get_object())
+
+    def test_instance_dti(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class AClass(object):\n    pass\n' \
+               '\ndef a_func(arg):\n    return eval("arg()")\n' \
+               'a_var = a_func(AClass)\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        self.assertEquals(pymod['AClass'].get_object(),
+                          pymod['a_var'].get_object().get_type())
+
+    def test_method_dti(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class AClass(object):\n    def a_method(self, arg):\n' \
+               '        return eval("arg()")\n' \
+               'an_instance = AClass()\n' \
+               'a_var = an_instance.a_method(AClass)\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        self.assertEquals(pymod['AClass'].get_object(),
+                          pymod['a_var'].get_object().get_type())
+
+    def test_function_argument_dti(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'def a_func(arg):\n    pass\n' \
+               'a_func(a_func)\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pyscope = self.pycore.resource_to_pyobject(mod).get_scope()
+        self.assertEquals(pyscope['a_func'].get_object(),
+                          pyscope.get_scopes()[0]['arg'].get_object())
+
+    def test_classes_with_the_same_name(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'def a_func(arg):\n    class AClass(object):\n' \
+               '        pass\n    return eval("arg")\n' \
+               'class AClass(object):\n    pass\n' \
+               'a_var = a_func(AClass)\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        self.assertEquals(pymod['AClass'].get_object(),
+                          pymod['a_var'].get_object())
+
+    def test_nested_classes(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'def a_func():\n    class AClass(object):\n' \
+               '        pass\n    return AClass\n' \
+               'def another_func(arg):\n    return eval("arg")\n' \
+               'a_var = another_func(a_func())\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pyscope = self.pycore.resource_to_pyobject(mod).get_scope()
+        self.assertEquals(pyscope.get_scopes()[0]['AClass'].get_object(),
+                          pyscope['a_var'].get_object())
+
+    def test_function_argument_dti2(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'def a_func(arg, a_builtin_type):\n    pass\n' \
+               'a_func(a_func, [])\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pyscope = self.pycore.resource_to_pyobject(mod).get_scope()
+        self.assertEquals(pyscope['a_func'].get_object(),
+                          pyscope.get_scopes()[0]['arg'].get_object())
+
+    def test_dti_and_concluded_data_invalidation(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'def a_func(arg):\n    return eval("arg")\n' \
+               'a_var = a_func(a_func)\n'
+        mod.write(code)
+        pymod = self.pycore.resource_to_pyobject(mod)
+        pymod['a_var'].get_object()
+        self.pycore.run_module(mod).wait_process()
+        self.assertEquals(pymod['a_func'].get_object(),
+                          pymod['a_var'].get_object())
+
+    def test_list_objects_and_dynamicoi(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C(object):\n    pass\n' \
+               'def a_func(arg):\n    return eval("arg")\n' \
+               'a_var = a_func([C()])[0]\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_for_loops_and_dynamicoi(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C(object):\n    pass\n' \
+               'def a_func(arg):\n    return eval("arg")\n' \
+               'for c in a_func([C()]):\n    a_var = c\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_dict_objects_and_dynamicoi(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C(object):\n    pass\n' \
+               'def a_func(arg):\n    return eval("arg")\n' \
+               'a_var = a_func({1: C()})[1]\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_dict_keys_and_dynamicoi(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C(object):\n    pass\n' \
+               'def a_func(arg):\n    return eval("arg")\n' \
+               'a_var = a_func({C(): 1}).keys()[0]\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_dict_keys_and_dynamicoi2(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C1(object):\n    pass\nclass C2(object):\n    pass\n' \
+               'def a_func(arg):\n    return eval("arg")\n' \
+               'a, b = a_func((C1(), C2()))\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_strs_and_dynamicoi(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'def a_func(arg):\n    return eval("arg")\n' \
+               'a_var = a_func("hey")\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        a_var = pymod['a_var'].get_object()
+        self.assertTrue(isinstance(a_var.get_type(), rope.base.builtins.Str))
+
+    def test_textual_transformations(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C(object):\n    pass\ndef f():\n    pass\na_var = C()\n' \
+               'a_list = [C()]\na_str = "hey"\na_file = open("file.txt")\n'
+        mod.write(code)
+        to_pyobject = rope.base.oi.transform.TextualToPyObject(self.project)
+        to_textual = rope.base.oi.transform.PyObjectToTextual(self.project)
+        pymod = self.pycore.resource_to_pyobject(mod)
+        def complex_to_textual(pyobject):
+            return to_textual.transform(
+                to_pyobject.transform(to_textual.transform(pyobject)))
+        for name in ('C', 'f', 'a_var', 'a_list', 'a_str', 'a_file'):
+            var = pymod[name].get_object()
+            self.assertEquals(to_textual.transform(var), complex_to_textual(var))
+        self.assertEquals(to_textual.transform(pymod), complex_to_textual(pymod))
+        enumerate_func = rope.base.builtins.builtins['enumerate'].get_object()
+        self.assertEquals(to_textual.transform(enumerate_func),
+                          complex_to_textual(enumerate_func))
+
+    def test_arguments_with_keywords(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C1(object):\n    pass\nclass C2(object):\n    pass\n' \
+               'def a_func(arg):\n    return eval("arg")\n' \
+               'a = a_func(arg=C1())\nb = a_func(arg=C2())\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_a_function_with_different_returns(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C1(object):\n    pass\nclass C2(object):\n    pass\n' \
+               'def a_func(arg):\n    return eval("arg")\n' \
+               'a = a_func(C1())\nb = a_func(C2())\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_a_function_with_different_returns2(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C1(object):\n    pass\nclass C2(object):\n    pass\n' \
+               'def a_func(p):\n    if p == C1:\n        return C1()\n' \
+               '    else:\n        return C2()\n' \
+               'a = a_func(C1)\nb = a_func(C2)\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_ignoring_star_args(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C1(object):\n    pass\nclass C2(object):\n    pass\n' \
+               'def a_func(p, *args):\n    if p == C1:\n        return C1()\n' \
+               '    else:\n        return C2()\n' \
+               'a = a_func(C1, 1)\nb = a_func(C2, 2)\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_ignoring_double_star_args(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C1(object):\n    pass\nclass C2(object):\n    pass\n' \
+               'def a_func(p, *kwds, **args):\n    if p == C1:\n        return C1()\n' \
+               '    else:\n        return C2()\n' \
+               'a = a_func(C1, kwd=1)\nb = a_func(C2, kwd=2)\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        pymod = self.pycore.resource_to_pyobject(mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_invalidating_data_after_changing(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'def a_func(arg):\n    return eval("arg")\n' \
+               'a_var = a_func(a_func)\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        mod.write(code.replace('a_func', 'newfunc'))
+        mod.write(code)
+        pymod = self.pycore.resource_to_pyobject(mod)
+        self.assertNotEquals(pymod['a_func'].get_object(),
+                             pymod['a_var'].get_object())
+
+    def test_invalidating_data_after_moving(self):
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod2.write('class C(object):\n    pass\n')
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'import mod2\ndef a_func(arg):\n    return eval(arg)\n' \
+               'a_var = a_func("mod2.C")\n'
+        mod.write(code)
+        self.pycore.run_module(mod).wait_process()
+        mod.move('newmod.py')
+        pymod = self.pycore.get_module('newmod')
+        pymod2 = self.pycore.resource_to_pyobject(mod2)
+        self.assertEquals(pymod2['C'].get_object(),
+                          pymod['a_var'].get_object())
+
+
+class NewStaticOITest(unittest.TestCase):
+
+    def setUp(self):
+        super(NewStaticOITest, self).setUp()
+        self.project = testutils.sample_project(validate_objectdb=True)
+        self.pycore = self.project.pycore
+        self.mod = testutils.create_module(self.project, 'mod')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(NewStaticOITest, self).tearDown()
+
+    def test_static_oi_for_simple_function_calls(self):
+        code = 'class C(object):\n    pass\ndef f(p):\n    pass\nf(C())\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        f_scope = pymod['f'].get_object().get_scope()
+        p_type = f_scope['p'].get_object().get_type()
+        self.assertEquals(c_class, p_type)
+
+    def test_static_oi_not_failing_when_callin_callables(self):
+        code = 'class C(object):\n    pass\nC()\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+
+    def test_static_oi_for_nested_calls(self):
+        code = 'class C(object):\n    pass\ndef f(p):\n    pass\n' \
+               'def g(p):\n    return p\nf(g(C()))\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        f_scope = pymod['f'].get_object().get_scope()
+        p_type = f_scope['p'].get_object().get_type()
+        self.assertEquals(c_class, p_type)
+
+    def test_static_oi_class_methods(self):
+        code = 'class C(object):\n    def f(self, p):\n        pass\n' \
+               'C().f(C())'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        f_scope = c_class['f'].get_object().get_scope()
+        p_type = f_scope['p'].get_object().get_type()
+        self.assertEquals(c_class, p_type)
+
+    def test_static_oi_preventing_soi_maximum_recursion_exceptions(self):
+        code = 'item = {}\nfor item in item.keys():\n    pass\n'
+        self.mod.write(code)
+        try:
+            self.pycore.analyze_module(self.mod)
+        except RuntimeError, e:
+            self.fail(str(e))
+
+    def test_static_oi_for_infering_returned_types_from_functions_based_on_parameters(self):
+        code = 'class C(object):\n    pass\ndef func(p):\n    return p\n' \
+               'a_var = func(C())\n'
+        self.mod.write(code)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_a_function_with_different_returns(self):
+        code = 'class C1(object):\n    pass\nclass C2(object):\n    pass\n' \
+               'def a_func(arg):\n    return arg\n' \
+               'a = a_func(C1())\nb = a_func(C2())\n'
+        self.mod.write(code)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_not_reporting_out_of_date_information(self):
+        code = 'class C1(object):\n    pass\n' \
+               'def f(arg):\n    return C1()\na_var = f('')\n'
+        self.mod.write(code)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+
+        self.mod.write(code.replace('C1', 'C2'))
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c2_class, a_var.get_type())
+
+    def test_invalidating_concluded_data_in_a_function(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('def func(arg):\n    temp = arg\n    return temp\n')
+        mod2.write('import mod1\n'
+                   'class C1(object):\n    pass\n'
+                   'class C2(object):\n    pass\n'
+                   'a_var = mod1.func(C1())\n')
+        pymod2 = self.pycore.resource_to_pyobject(mod2)
+        c1_class = pymod2['C1'].get_object()
+        a_var = pymod2['a_var'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+
+        mod2.write(mod2.read()[:mod2.read().rfind('C1()')] + 'C2())\n')
+        pymod2 = self.pycore.resource_to_pyobject(mod2)
+        c2_class = pymod2['C2'].get_object()
+        a_var = pymod2['a_var'].get_object()
+        self.assertEquals(c2_class, a_var.get_type())
+
+    def test_handling_generator_functions_for_strs(self):
+        self.mod.write('class C(object):\n    pass\ndef f(p):\n    yield p()\n'
+                       'for c in f(C):\n    a_var = c\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    # TODO: Returning a generator for functions that yield unknowns
+    def xxx_test_handling_generator_functions_when_unknown_type_is_yielded(self):
+        self.mod.write('class C(object):\n    pass\ndef f():\n    yield eval("C()")\n'
+                       'a_var = f()\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        a_var = pymod['a_var'].get_object()
+        self.assertTrue(isinstance(a_var.get_type(),
+                                   rope.base.builtins.Generator))
+
+    def test_static_oi_for_lists_depending_on_append_function(self):
+        code = 'class C(object):\n    pass\nl = list()\n' \
+               'l.append(C())\na_var = l.pop()\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_static_oi_for_lists_per_object_for_get_item(self):
+        code = 'class C(object):\n    pass\nl = list()\n' \
+               'l.append(C())\na_var = l[0]\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_static_oi_for_lists_per_object_for_fields(self):
+        code = 'class C(object):\n    pass\n' \
+               'class A(object):\n    def __init__(self):\n        self.l = []\n' \
+               '    def set(self):\n        self.l.append(C())\n' \
+               'a = A()\na.set()\na_var = a.l[0]\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_static_oi_for_lists_per_object_for_set_item(self):
+        code = 'class C(object):\n    pass\nl = [None]\n' \
+               'l[0] = C()\na_var = l[0]\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_static_oi_for_lists_per_object_for_extending_lists(self):
+        code = 'class C(object):\n    pass\nl = []\n' \
+               'l.append(C())\nl2 = []\nl2.extend(l)\na_var = l2[0]\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_static_oi_for_lists_per_object_for_iters(self):
+        code = 'class C(object):\n    pass\n' \
+               'l = []\nl.append(C())\n' \
+               'for c in l:\n    a_var = c\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_static_oi_for_dicts_depending_on_append_function(self):
+        code = 'class C1(object):\n    pass\nclass C2(object):\n    pass\n' \
+               'd = {}\nd[C1()] = C2()\na, b = d.popitem()\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_static_oi_for_dicts_depending_on_for_loops(self):
+        code = 'class C1(object):\n    pass\nclass C2(object):\n    pass\n' \
+               'd = {}\nd[C1()] = C2()\nfor k, v in d.items():\n    a = k\n    b = v\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_static_oi_for_dicts_depending_on_update(self):
+        code = 'class C1(object):\n    pass\nclass C2(object):\n    pass\n' \
+               'd = {}\nd[C1()] = C2()\nd2 = {}\nd2.update(d)\na, b = d2.popitem()\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_static_oi_for_dicts_depending_on_update_on_seqs(self):
+        code = 'class C1(object):\n    pass\nclass C2(object):\n    pass\n' \
+               'd = {}\nd.update([(C1(), C2())])\na, b = d.popitem()\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_static_oi_for_sets_per_object_for_set_item(self):
+        code = 'class C(object):\n    pass\ns = set()\n' \
+               's.add(C())\na_var = s.pop() \n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_properties_and_calling_get_property(self):
+        code = 'class C1(object):\n    pass\n' \
+               'class C2(object):\n    c1 = C1()\n' \
+               '    def get_c1(self):\n        return self.c1\n' \
+               '    p = property(get_c1)\nc2 = C2()\na_var = c2.p\n'
+        self.mod.write(code)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+
+    def test_soi_on_constructors(self):
+        code = 'class C1(object):\n    pass\n' \
+               'class C2(object):\n' \
+               '    def __init__(self, arg):\n        self.attr = arg\n' \
+               'c2 = C2(C1())\na_var = c2.attr'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+
+    def test_not_saving_unknown_function_returns(self):
+        mod2 = testutils.create_module(self.project, 'mod2')
+        self.mod.write('class C(object):\n    pass\nl = []\nl.append(C())\n')
+        mod2.write('import mod\ndef f():\n    return mod.l.pop()\na_var = f()\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        pymod2 = self.pycore.resource_to_pyobject(mod2)
+        c_class = pymod['C'].get_object()
+        a_var = pymod2['a_var']
+
+        self.pycore.analyze_module(mod2)
+        self.assertNotEquals(c_class, a_var.get_object().get_type())
+
+        self.pycore.analyze_module(self.mod)
+        self.assertEquals(c_class, a_var.get_object().get_type())
+
+    def test_using_the_best_callinfo(self):
+        code = 'class C1(object):\n    pass\n' \
+               'def f(arg1, arg2, arg3):\n    pass\n' \
+               'f("", None, C1())\nf("", C1(), None)\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        f_scope = pymod['f'].get_object().get_scope()
+        arg2 = f_scope['arg2'].get_object()
+        self.assertEquals(c1_class, arg2.get_type())
+
+    def test_call_function_and_parameters(self):
+        code = 'class A(object):\n    def __call__(self, p):\n        pass\n' \
+               'A()("")\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        scope = self.pycore.resource_to_pyobject(self.mod).get_scope()
+        p_object = scope.get_scopes()[0].get_scopes()[0]['p'].get_object()
+        self.assertTrue(isinstance(p_object.get_type(),
+                                   rope.base.builtins.Str))
+
+    def test_report_change_in_libutils(self):
+        self.project.prefs['automatic_soa'] = True
+        code = 'class C(object):\n    pass\ndef f(p):\n    pass\nf(C())\n'
+        mod_file = open(self.mod.real_path, 'w')
+        mod_file.write(code)
+        mod_file.close()
+        rope.base.libutils.report_change(self.project, self.mod.real_path, '')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        f_scope = pymod['f'].get_object().get_scope()
+        p_type = f_scope['p'].get_object().get_type()
+        self.assertEquals(c_class, p_type)
+
+    def test_report_libutils_and_analyze_all_modules(self):
+        code = 'class C(object):\n    pass\ndef f(p):\n    pass\nf(C())\n'
+        self.mod.write(code)
+        rope.base.libutils.analyze_modules(self.project)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        f_scope = pymod['f'].get_object().get_scope()
+        p_type = f_scope['p'].get_object().get_type()
+        self.assertEquals(c_class, p_type)
+
+    def test_validation_problems_for_objectdb_retrievals(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('l = []\nvar = l.pop()\n')
+        mod2.write('import mod1\n\nclass C(object):\n    pass\n'
+                   'mod1.l.append(C())\n')
+        self.pycore.analyze_module(mod2)
+
+        pymod2 = self.pycore.resource_to_pyobject(mod2)
+        c_class = pymod2['C'].get_object()
+        pymod1 = self.pycore.resource_to_pyobject(mod1)
+        var_pyname = pymod1['var']
+        self.assertEquals(c_class, var_pyname.get_object().get_type())
+        mod2.write('import mod1\n\nmod1.l.append("")\n')
+        self.assertNotEquals(c_class, var_pyname.get_object().get_type(),
+                             'Class `C` no more exists')
+
+    def test_validation_problems_for_changing_builtin_types(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('l = []\nl.append("")\n')
+        self.pycore.analyze_module(mod1)
+
+        mod1.write('l = {}\nv = l["key"]\n')
+        pymod1 = self.pycore.resource_to_pyobject(mod1)
+        var = pymod1['v'].get_object()
+
+    def test_always_returning_containing_class_for_selfs(self):
+        code = 'class A(object):\n    def f(p):\n        return p\n' \
+               'class B(object):\n    pass\nb = B()\nb.f()\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        a_class = pymod['A'].get_object()
+        f_scope = a_class.get_scope().get_scopes()[0]
+        p_type = f_scope['p'].get_object().get_type()
+        self.assertEquals(a_class, p_type)
+
+    def test_following_function_calls_when_asked_to(self):
+        code = 'class A(object):\n    pass\n' \
+               'class C(object):\n' \
+               '    def __init__(self, arg):\n' \
+               '        self.attr = arg\n' \
+               'def f(p):\n    return C(p)\n' \
+               'c = f(A())\nx = c.attr\n'
+        self.mod.write(code)
+        self.pycore.analyze_module(self.mod, followed_calls=1)
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        a_class = pymod['A'].get_object()
+        x_var = pymod['x'].get_object().get_type()
+        self.assertEquals(a_class, x_var)
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(DynamicOITest))
+    result.addTests(unittest.makeSuite(NewStaticOITest))
+    return result
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/builtinstest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,482 @@
+import unittest
+
+from rope.base import pyobjects, builtins
+from ropetest import testutils
+
+
+class BuiltinTypesTest(unittest.TestCase):
+
+    def setUp(self):
+        super(BuiltinTypesTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+        self.mod = testutils.create_module(self.project, 'mod')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(BuiltinTypesTest, self).tearDown()
+
+    def test_simple_case(self):
+        self.mod.write('l = []\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertTrue('append' in pymod['l'].get_object())
+
+    def test_holding_type_information(self):
+        self.mod.write('class C(object):\n    pass\nl = [C()]\na_var = l.pop()\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_get_items(self):
+        self.mod.write('class C(object):\n    def __getitem__(self, i):\n        return C()\n'
+                       'c = C()\na_var = c[0]')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_get_items_for_lists(self):
+        self.mod.write('class C(object):\n    pass\nl = [C()]\na_var = l[0]\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_get_items_from_slices(self):
+        self.mod.write('class C(object):\n    pass\nl = [C()]\na_var = l[:].pop()\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_simple_for_loops(self):
+        self.mod.write('class C(object):\n    pass\nl = [C()]\n'
+                       'for c in l:\n    a_var = c\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_definition_location_for_loop_variables(self):
+        self.mod.write('class C(object):\n    pass\nl = [C()]\n'
+                       'for c in l:\n    pass\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_var = pymod['c']
+        self.assertEquals((pymod, 4), c_var.get_definition_location())
+
+    def test_simple_case_for_dicts(self):
+        self.mod.write('d = {}\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertTrue('get' in pymod['d'].get_object())
+
+    def test_get_item_for_dicts(self):
+        self.mod.write('class C(object):\n    pass\nd = {1: C()}\na_var = d[1]\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_popping_dicts(self):
+        self.mod.write('class C(object):\n    pass\nd = {1: C()}\na_var = d.pop(1)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_getting_keys_from_dicts(self):
+        self.mod.write('class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+                       'd = {C1(): C2()}\nfor c in d.keys():\n    a_var = c\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C1'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_getting_values_from_dicts(self):
+        self.mod.write('class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+                       'd = {C1(): C2()}\nfor c in d.values():\n    a_var = c\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C2'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_getting_iterkeys_from_dicts(self):
+        self.mod.write('class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+                       'd = {C1(): C2()}\nfor c in d.keys():\n    a_var = c\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C1'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_getting_itervalues_from_dicts(self):
+        self.mod.write('class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+                       'd = {C1(): C2()}\nfor c in d.values():\n    a_var = c\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C2'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_using_copy_for_dicts(self):
+        self.mod.write('class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+                       'd = {C1(): C2()}\nfor c in d.copy():\n    a_var = c\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C1'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_tuple_assignments_for_items(self):
+        self.mod.write('class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+                       'd = {C1(): C2()}\nkey, value = d.items()[0]\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        key = pymod['key'].get_object()
+        value = pymod['value'].get_object()
+        self.assertEquals(c1_class, key.get_type())
+        self.assertEquals(c2_class, value.get_type())
+
+    def test_tuple_assignment_for_lists(self):
+        self.mod.write('class C(object):\n    pass\nl = [C(), C()]\na, b = l\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+        self.assertEquals(c_class, b_var.get_type())
+
+    def test_tuple_assignments_for_iteritems_in_fors(self):
+        self.mod.write('class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+                       'd = {C1(): C2()}\nfor x, y in d.items():\n    a = x;\n    b = y\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_simple_tuple_assignments(self):
+        self.mod.write('class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+                       'a, b = C1(), C2()\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_overriding_builtin_names(self):
+        self.mod.write('class C(object):\n    pass\nlist = C\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        list_var = pymod['list'].get_object()
+        self.assertEquals(c_class, list_var)
+
+    def test_simple_builtin_scope_test(self):
+        self.mod.write('l = list()\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertTrue('append' in pymod['l'].get_object())
+
+    def test_simple_sets(self):
+        self.mod.write('s = set()\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertTrue('add' in pymod['s'].get_object())
+
+    def test_making_lists_using_the_passed_argument_to_init(self):
+        self.mod.write('class C(object):\n    pass\nl1 = [C()]\n'
+                       'l2 = list(l1)\na_var = l2.pop()')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_making_tuples_using_the_passed_argument_to_init(self):
+        self.mod.write('class C(object):\n    pass\nl1 = [C()]\n'
+                       'l2 = tuple(l1)\na_var = l2[0]')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_making_sets_using_the_passed_argument_to_init(self):
+        self.mod.write('class C(object):\n    pass\nl1 = [C()]\n'
+                       'l2 = set(l1)\na_var = l2.pop()')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_making_dicts_using_the_passed_argument_to_init(self):
+        self.mod.write('class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+                       'l1 = [(C1(), C2())]\n'
+                       'l2 = dict(l1)\na, b = l2.items()[0]')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_range_builtin_function(self):
+        self.mod.write('l = range(1)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        l = pymod['l'].get_object()
+        self.assertTrue('append' in l)
+
+    def test_reversed_builtin_function(self):
+        self.mod.write('class C(object):\n    pass\nl = [C()]\n'
+                       'for x in reversed(l):\n    a_var = x\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_sorted_builtin_function(self):
+        self.mod.write('class C(object):\n    pass\nl = [C()]\n'
+                       'a_var = sorted(l).pop()\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_super_builtin_function(self):
+        self.mod.write(
+            'class C(object):\n    pass\n'
+            'class A(object):\n    def a_f(self):\n        return C()\n'
+            'class B(A):\n    def b_f(self):\n        return super(B, self).a_f()\n'
+            'a_var = B.b_f()\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_file_builtin_type(self):
+        self.mod.write('for line in open("file.txt"):\n    a_var = line\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        a_var = pymod['a_var'].get_object()
+        self.assertTrue(isinstance(a_var.get_type(), builtins.Str))
+
+    def test_property_builtin_type(self):
+        self.mod.write('p = property()\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        p_var = pymod['p'].get_object()
+        self.assertTrue('fget' in p_var)
+
+    def test_lambda_functions(self):
+        self.mod.write('l = lambda: 1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        l_var = pymod['l'].get_object()
+        self.assertEquals(pyobjects.get_base_type('Function'),
+                          l_var.get_type())
+
+    def test_lambda_function_definition(self):
+        self.mod.write('l = lambda x, y = 2, *a, **b: x + y\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        l_var = pymod['l'].get_object()
+        self.assertTrue(l_var.get_name() is not None)
+        self.assertEquals(len(l_var.get_param_names()), 4)
+        self.assertEquals((pymod, 1),
+                          pymod['l'].get_definition_location())
+
+    def test_lambdas_that_return_unknown(self):
+        self.mod.write('a_var = (lambda: None)()\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        a_var = pymod['a_var'].get_object()
+        self.assertTrue(a_var is not None)
+
+    def test_builtin_zip_function(self):
+        self.mod.write(
+            'class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+            'c1_list = [C1()]\nc2_list = [C2()]\n'
+            'a, b = zip(c1_list, c2_list)[0]')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_builtin_zip_function_with_more_than_two_args(self):
+        self.mod.write(
+            'class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+            'c1_list = [C1()]\nc2_list = [C2()]\n'
+            'a, b, c = zip(c1_list, c2_list, c1_list)[0]')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        c2_class = pymod['C2'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        c_var = pymod['c'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+        self.assertEquals(c1_class, c_var.get_type())
+
+    def test_wrong_arguments_to_zip_function(self):
+        self.mod.write(
+            'class C1(object):\n    pass\nc1_list = [C1()]\n'
+            'a, b = zip(c1_list, 1)[0]')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c1_class = pymod['C1'].get_object()
+        a_var = pymod['a'].get_object()
+        b_var = pymod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+
+    def test_enumerate_builtin_function(self):
+        self.mod.write('class C(object):\n    pass\nl = [C()]\n'
+                       'for i, x in enumerate(l):\n    a_var = x\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_builtin_class_get_name(self):
+        self.assertEquals('object',
+                          builtins.builtins['object'].get_object().get_name())
+        self.assertEquals('property',
+                          builtins.builtins['property'].get_object().get_name())
+
+    def test_star_args_and_double_star_args(self):
+        self.mod.write('def func(p, *args, **kwds):\n    pass\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        func_scope = pymod['func'].get_object().get_scope()
+        args = func_scope['args'].get_object()
+        kwds = func_scope['kwds'].get_object()
+        self.assertTrue(isinstance(args.get_type(), builtins.List))
+        self.assertTrue(isinstance(kwds.get_type(), builtins.Dict))
+
+    def test_simple_list_comprehension_test(self):
+        self.mod.write('a_var = [i for i in range(10)]\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        a_var = pymod['a_var'].get_object()
+        self.assertTrue(isinstance(a_var.get_type(), builtins.List))
+
+    def test_simple_list_generator_expression(self):
+        self.mod.write('a_var = (i for i in range(10))\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        a_var = pymod['a_var'].get_object()
+        self.assertTrue(isinstance(a_var.get_type(), builtins.Iterator))
+
+    def test_iter_builtin_function(self):
+        self.mod.write('class C(object):\n    pass\nl = [C()]\n'
+                       'for c in iter(l):\n    a_var = c\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        c_class = pymod['C'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_simple_int_type(self):
+        self.mod.write('l = 1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(builtins.builtins['int'].get_object(),
+                          pymod['l'].get_object().get_type())
+
+    def test_simple_float_type(self):
+        self.mod.write('l = 1.0\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(builtins.builtins['float'].get_object(),
+                          pymod['l'].get_object().get_type())
+
+    def test_simple_float_type2(self):
+        self.mod.write('l = 1e1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(builtins.builtins['float'].get_object(),
+                          pymod['l'].get_object().get_type())
+
+    def test_simple_complex_type(self):
+        self.mod.write('l = 1.0j\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(builtins.builtins['complex'].get_object(),
+                          pymod['l'].get_object().get_type())
+
+    def test_handling_unaryop_on_ints(self):
+        self.mod.write('l = -(1)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(builtins.builtins['int'].get_object(),
+                          pymod['l'].get_object().get_type())
+
+    def test_handling_binop_on_ints(self):
+        self.mod.write('l = 1 + 1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(builtins.builtins['int'].get_object(),
+                          pymod['l'].get_object().get_type())
+
+    def test_handling_compares(self):
+        self.mod.write('l = 1 == 1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(builtins.builtins['bool'].get_object(),
+                          pymod['l'].get_object().get_type())
+
+    def test_handling_boolops(self):
+        self.mod.write('l = 1 and 2\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(builtins.builtins['int'].get_object(),
+                          pymod['l'].get_object().get_type())
+
+    def test_binary_or_left_value_unknown(self):
+        code = 'var = (asdsd or 3)\n'
+        pymod = self.pycore.get_string_module(code)
+        self.assertEquals(builtins.builtins['int'].get_object(),
+                          pymod['var'].get_object().get_type())
+
+    def test_unknown_return_object(self):
+        src = 'import sys\n' \
+              'def foo():\n' \
+              '  res = set(sys.builtin_module_names)\n' \
+              '  if foo: res.add(bar)\n'
+        self.project.prefs['import_dynload_stdmods'] = True
+        self.mod.write(src)
+        self.project.pycore.analyze_module(self.mod)
+
+
+class BuiltinModulesTest(unittest.TestCase):
+
+    def setUp(self):
+        super(BuiltinModulesTest, self).setUp()
+        self.project = testutils.sample_project(
+            extension_modules=['time', 'invalid', 'invalid.sub'])
+        self.pycore = self.project.pycore
+        self.mod = testutils.create_module(self.project, 'mod')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(BuiltinModulesTest, self).tearDown()
+
+    def test_simple_case(self):
+        self.mod.write('import time')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertTrue('time' in pymod['time'].get_object())
+
+    def test_ignored_extensions(self):
+        self.mod.write('import os')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertTrue('rename' not in pymod['os'].get_object())
+
+    def test_ignored_extensions(self):
+        self.mod.write('import os')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertTrue('rename' not in pymod['os'].get_object())
+
+    def test_nonexistent_modules(self):
+        self.mod.write('import invalid')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        pymod['invalid'].get_object()
+
+    def test_nonexistent_modules(self):
+        self.mod.write('import invalid\nimport invalid.sub')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        invalid = pymod['invalid'].get_object()
+        self.assertTrue('sub' in invalid)
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(BuiltinTypesTest))
+    result.addTests(unittest.makeSuite(BuiltinModulesTest))
+    return result
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/codeanalyzetest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,616 @@
+import unittest
+
+import rope.base.evaluate
+from rope.base import exceptions, ast, worder, codeanalyze
+from rope.base.codeanalyze import SourceLinesAdapter, LogicalLineFinder, get_block_start
+from ropetest import testutils
+
+
+class SourceLinesAdapterTest(unittest.TestCase):
+
+    def setUp(self):
+        super(SourceLinesAdapterTest, self).setUp()
+
+    def tearDown(self):
+        super(SourceLinesAdapterTest, self).tearDown()
+
+    def test_source_lines_simple(self):
+        to_lines = SourceLinesAdapter('line1\nline2\n')
+        self.assertEquals('line1', to_lines.get_line(1))
+        self.assertEquals('line2', to_lines.get_line(2))
+        self.assertEquals('', to_lines.get_line(3))
+        self.assertEquals(3, to_lines.length())
+
+    def test_source_lines_get_line_number(self):
+        to_lines = SourceLinesAdapter('line1\nline2\n')
+        self.assertEquals(1, to_lines.get_line_number(0))
+        self.assertEquals(1, to_lines.get_line_number(5))
+        self.assertEquals(2, to_lines.get_line_number(7))
+        self.assertEquals(3, to_lines.get_line_number(12))
+
+    def test_source_lines_get_line_start(self):
+        to_lines = SourceLinesAdapter('line1\nline2\n')
+        self.assertEquals(0, to_lines.get_line_start(1))
+        self.assertEquals(6, to_lines.get_line_start(2))
+        self.assertEquals(12, to_lines.get_line_start(3))
+
+    def test_source_lines_get_line_end(self):
+        to_lines = SourceLinesAdapter('line1\nline2\n')
+        self.assertEquals(5, to_lines.get_line_end(1))
+        self.assertEquals(11, to_lines.get_line_end(2))
+        self.assertEquals(12, to_lines.get_line_end(3))
+
+    def test_source_lines_last_line_with_no_new_line(self):
+        to_lines = SourceLinesAdapter('line1')
+        self.assertEquals(1, to_lines.get_line_number(5))
+
+
+class WordRangeFinderTest(unittest.TestCase):
+
+    def setUp(self):
+        super(WordRangeFinderTest, self).setUp()
+
+    def tearDown(self):
+        super(WordRangeFinderTest, self).tearDown()
+
+    def _find_primary(self, code, offset):
+        word_finder = worder.Worder(code)
+        result = word_finder.get_primary_at(offset)
+        return result
+
+    def test_keyword_before_parens(self):
+        code = 'if (a_var).an_attr:\n    pass\n'
+        self.assertEquals('(a_var).an_attr',
+                          self._find_primary(code, code.index(':')))
+
+    def test_inside_parans(self):
+        code = 'a_func(a_var)'
+        self.assertEquals('a_var', self._find_primary(code, 10))
+
+    def test_simple_names(self):
+        code = 'a_var = 10'
+        self.assertEquals('a_var', self._find_primary(code, 3))
+
+    def test_function_calls(self):
+        code = 'sample_function()'
+        self.assertEquals('sample_function', self._find_primary(code, 10))
+
+    def test_attribute_accesses(self):
+        code = 'a_var.an_attr'
+        self.assertEquals('a_var.an_attr', self._find_primary(code, 10))
+
+    def test_word_finder_on_word_beginning(self):
+        code = 'print a_var\n'
+        word_finder = worder.Worder(code)
+        result = word_finder.get_word_at(code.index('a_var'))
+        self.assertEquals('a_var', result)
+
+    def test_word_finder_on_primary_beginning(self):
+        code = 'print a_var\n'
+        result = self._find_primary(code, code.index('a_var'))
+        self.assertEquals('a_var', result)
+
+    def test_word_finder_on_word_ending(self):
+        code = 'print a_var\n'
+        word_finder = worder.Worder(code)
+        result = word_finder.get_word_at(code.index('a_var') + 5)
+        self.assertEquals('a_var', result)
+
+    def test_word_finder_on_primary_ending(self):
+        code = 'print a_var\n'
+        result = self._find_primary(code, code.index('a_var') + 5)
+        self.assertEquals('a_var', result)
+
+    def test_word_finder_on_primaries_with_dots_inside_parens(self):
+        code = '(a_var.\nattr)'
+        result = self._find_primary(code, code.index('attr') + 1)
+        self.assertEquals('a_var.\nattr', result)
+
+    def test_strings(self):
+        code = '"a string".split()'
+        self.assertEquals('"a string".split', self._find_primary(code, 14))
+
+    def test_function_calls2(self):
+        code = 'file("afile.txt").read()'
+        self.assertEquals('file("afile.txt").read', self._find_primary(code, 18))
+
+    def test_parens(self):
+        code = '("afile.txt").split()'
+        self.assertEquals('("afile.txt").split', self._find_primary(code, 18))
+
+    def test_function_with_no_param(self):
+        code = 'AClass().a_func()'
+        self.assertEquals('AClass().a_func', self._find_primary(code, 12))
+
+    def test_function_with_multiple_param(self):
+        code = 'AClass(a_param, another_param, "a string").a_func()'
+        self.assertEquals('AClass(a_param, another_param, "a string").a_func',
+                          self._find_primary(code, 44))
+
+    def test_param_expressions(self):
+        code = 'AClass(an_object.an_attr).a_func()'
+        self.assertEquals('an_object.an_attr', self._find_primary(code, 20))
+
+    def test_string_parens(self):
+        code = 'a_func("(").an_attr'
+        self.assertEquals('a_func("(").an_attr', self._find_primary(code, 16))
+
+    def test_extra_spaces(self):
+        code = 'a_func  (  "(" ) .   an_attr'
+        self.assertEquals('a_func  (  "(" ) .   an_attr',
+                          self._find_primary(code, 26))
+
+    def test_functions_on_ending_parens(self):
+        code = 'A()'
+        self.assertEquals('A()', self._find_primary(code, 2))
+
+    def test_splitted_statement(self):
+        word_finder = worder.Worder('an_object.an_attr')
+        self.assertEquals(('an_object', 'an_at', 10),
+                          word_finder.get_splitted_primary_before(15))
+
+    def test_empty_splitted_statement(self):
+        word_finder = worder.Worder('an_attr')
+        self.assertEquals(('', 'an_at', 0),
+                          word_finder.get_splitted_primary_before(5))
+
+    def test_empty_splitted_statement2(self):
+        word_finder = worder.Worder('an_object.')
+        self.assertEquals(('an_object', '', 10),
+                          word_finder.get_splitted_primary_before(10))
+
+    def test_empty_splitted_statement3(self):
+        word_finder = worder.Worder('')
+        self.assertEquals(('', '', 0),
+                          word_finder.get_splitted_primary_before(0))
+
+    def test_empty_splitted_statement4(self):
+        word_finder = worder.Worder('a_var = ')
+        self.assertEquals(('', '', 8),
+                          word_finder.get_splitted_primary_before(8))
+
+    def test_empty_splitted_statement5(self):
+        word_finder = worder.Worder('a.')
+        self.assertEquals(('a', '', 2),
+                          word_finder.get_splitted_primary_before(2))
+
+    def test_operators_inside_parens(self):
+        code = '(a_var + another_var).reverse()'
+        self.assertEquals('(a_var + another_var).reverse',
+                          self._find_primary(code, 25))
+
+    def test_dictionaries(self):
+        code = 'print {1: "one", 2: "two"}.keys()'
+        self.assertEquals('{1: "one", 2: "two"}.keys',
+                          self._find_primary(code, 29))
+
+    def test_following_parens(self):
+        code = 'a_var = a_func()()'
+        result = self._find_primary(code, code.index(')(') + 3)
+        self.assertEquals('a_func()()', result)
+
+    def test_comments_for_finding_statements(self):
+        code = '# var2 . \n  var3'
+        self.assertEquals('var3', self._find_primary(code, code.index('3')))
+
+    def test_str_in_comments_for_finding_statements(self):
+        code = '# "var2" . \n  var3'
+        self.assertEquals('var3', self._find_primary(code, code.index('3')))
+
+    def test_comments_for_finding_statements2(self):
+        code = 'var1 + "# var2".\n  var3'
+        self.assertEquals('var3', self._find_primary(code, 21))
+
+    def test_comments_for_finding_statements3(self):
+        code = '"" + # var2.\n  var3'
+        self.assertEquals('var3', self._find_primary(code, 21))
+
+    def test_import_statement_finding(self):
+        code = 'import mod\na_var = 10\n'
+        word_finder = worder.Worder(code)
+        self.assertTrue(word_finder.is_import_statement(code.index('mod') + 1))
+        self.assertFalse(word_finder.is_import_statement(code.index('a_var') + 1))
+
+    def test_import_statement_finding2(self):
+        code = 'import a.b.c.d\nresult = a.b.c.d.f()\n'
+        word_finder = worder.Worder(code)
+        self.assertFalse(word_finder.is_import_statement(code.rindex('d') + 1))
+
+    def test_word_parens_range(self):
+        code = 's = str()\ns.title()\n'
+        word_finder = worder.Worder(code)
+        result = word_finder.get_word_parens_range(code.rindex('()') - 1)
+        self.assertEquals((len(code) - 3, len(code) - 1), result)
+
+    def test_getting_primary_before_get_index(self):
+        code = '\na = (b + c).d[0]()\n'
+        result = self._find_primary(code, len(code) - 2)
+        self.assertEquals('(b + c).d[0]()', result)
+
+    def test_getting_primary_and_strings_at_the_end_of_line(self):
+        code = 'f(\'\\\'\')\n'
+        result = self._find_primary(code, len(code) - 1)
+
+    def test_getting_primary_and_not_crossing_newlines(self):
+        code = '\na = (b + c)\n(4 + 1).x\n'
+        result = self._find_primary(code, len(code) - 1)
+        self.assertEquals('(4 + 1).x', result)
+
+    # XXX: cancatenated string literals
+    def xxx_test_getting_primary_cancatenating_strs(self):
+        code = 's = "a"\n"b" "c"\n'
+        result = self._find_primary(code, len(code) - 2)
+        self.assertEquals('"b" "c"', result)
+
+    def test_is_a_function_being_called_with_parens_on_next_line(self):
+        code = 'func\n(1, 2)\n'
+        word_finder = worder.Worder(code)
+        self.assertFalse(word_finder.is_a_function_being_called(1))
+
+    # XXX: handling triple quotes
+    def xxx_test_triple_quotes(self):
+        code = 's = """string"""\n'
+        result = self._find_primary(code, len(code) - 1)
+        self.assertEquals('"""string"""', result)
+
+    def test_triple_quotes_spanning_multiple_lines(self):
+        code = 's = """\\\nl1\nl2\n """\n'
+        result = self._find_primary(code, len(code) - 2)
+        self.assertEquals('"""\\\nl1\nl2\n """', result)
+
+    def test_get_word_parens_range_and_string_literals(self):
+        code = 'f(1, ")", 2)\n'
+        word_finder = worder.Worder(code)
+        result = word_finder.get_word_parens_range(0)
+        self.assertEquals((1, len(code) - 1), result)
+
+    def test_is_assigned_here_for_equality_test(self):
+        code = 'a == 1\n'
+        word_finder = worder.Worder(code)
+        self.assertFalse(word_finder.is_assigned_here(0))
+
+    def test_is_assigned_here_for_not_equal_test(self):
+        code = 'a != 1\n'
+        word_finder = worder.Worder(code)
+        self.assertFalse(word_finder.is_assigned_here(0))
+
+    # XXX: is_assigned_here should work for tuple assignments
+    def xxx_test_is_assigned_here_for_tuple_assignment(self):
+        code = 'a, b = (1, 2)\n'
+        word_finder = worder.Worder(code)
+        self.assertTrue(word_finder.is_assigned_here(0))
+
+    def test_is_from_with_from_import_and_multiline_parens(self):
+        code = 'from mod import \\\n  (f,\n  g, h)\n'
+        word_finder = worder.Worder(code)
+        self.assertTrue(word_finder.is_from_statement(code.rindex('g')))
+
+    def test_is_from_with_from_import_and_line_breaks_in_the_middle(self):
+        code = 'from mod import f,\\\n g\n'
+        word_finder = worder.Worder(code)
+        self.assertTrue(word_finder.is_from_statement(code.rindex('g')))
+
+    def test_one_letter_function_keyword_arguments(self):
+        code = 'f(p=1)\n'
+        word_finder = worder.Worder(code)
+        index = code.rindex('p')
+        self.assertTrue(word_finder.is_function_keyword_parameter(index))
+
+    def test_find_parens_start(self):
+        code = 'f(p)\n'
+        finder = worder.Worder(code)
+        self.assertEquals(1, finder.find_parens_start_from_inside(2))
+
+    def test_underlined_find_parens_start(self):
+        code = 'f(p="")\n'
+        finder = worder.Worder(code)
+        self.assertEquals(1, finder._find_parens_start(len(code) - 2))
+
+    def test_find_parens_start_with_multiple_entries(self):
+        code = 'myfunc(p1, p2, p3\n'
+        finder = worder.Worder(code)
+        self.assertEquals(code.index('('),
+                          finder.find_parens_start_from_inside(len(code) - 1))
+
+    def test_find_parens_start_with_nested_parens(self):
+        code = 'myfunc(p1, (p2, p3), p4\n'
+        finder = worder.Worder(code)
+        self.assertEquals(code.index('('),
+                          finder.find_parens_start_from_inside(len(code) - 1))
+
+    def test_find_parens_start_with_parens_in_strs(self):
+        code = 'myfunc(p1, "(", p4\n'
+        finder = worder.Worder(code)
+        self.assertEquals(code.index('('),
+                          finder.find_parens_start_from_inside(len(code) - 1))
+
+    def test_find_parens_start_with_parens_in_strs_in_multiple_lines(self):
+        code = 'myfunc  (\np1\n , \n "(" \n, \np4\n'
+        finder = worder.Worder(code)
+        self.assertEquals(code.index('('),
+                          finder.find_parens_start_from_inside(len(code) - 1))
+
+    def test_is_on_function_keyword(self):
+        code = 'myfunc(va'
+        finder = worder.Worder(code)
+        self.assertTrue(finder.is_on_function_call_keyword(len(code) - 1))
+
+
+class ScopeNameFinderTest(unittest.TestCase):
+
+    def setUp(self):
+        super(ScopeNameFinderTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(ScopeNameFinderTest, self).tearDown()
+
+    # FIXME: in normal scopes the interpreter raises `UnboundLocalName`
+    # exception, but not in class bodies
+    def xxx_test_global_name_in_class_body(self):
+        code = 'a_var = 10\nclass C(object):\n    a_var = a_var\n'
+        scope = self.pycore.get_string_scope(code)
+        name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject)
+        result = name_finder.get_pyname_at(len(code) - 3)
+        self.assertEquals(scope['a_var'], result)
+
+    def test_class_variable_attribute_in_class_body(self):
+        code = 'a_var = 10\nclass C(object):\n    a_var = a_var\n'
+        scope = self.pycore.get_string_scope(code)
+        name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject)
+        a_var_pyname = scope['C'].get_object()['a_var']
+        result = name_finder.get_pyname_at(len(code) - 12)
+        self.assertEquals(a_var_pyname, result)
+
+    def test_class_variable_attribute_in_class_body2(self):
+        code = 'a_var = 10\nclass C(object):\n    a_var \\\n= a_var\n'
+        scope = self.pycore.get_string_scope(code)
+        name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject)
+        a_var_pyname = scope['C'].get_object()['a_var']
+        result = name_finder.get_pyname_at(len(code) - 12)
+        self.assertEquals(a_var_pyname, result)
+
+    def test_class_method_attribute_in_class_body(self):
+        code = 'class C(object):\n    def a_method(self):\n        pass\n'
+        scope = self.pycore.get_string_scope(code)
+        name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject)
+        a_method_pyname = scope['C'].get_object()['a_method']
+        result = name_finder.get_pyname_at(code.index('a_method') + 2)
+        self.assertEquals(a_method_pyname, result)
+
+    def test_inner_class_attribute_in_class_body(self):
+        code = 'class C(object):\n    class CC(object):\n        pass\n'
+        scope = self.pycore.get_string_scope(code)
+        name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject)
+        a_class_pyname = scope['C'].get_object()['CC']
+        result = name_finder.get_pyname_at(code.index('CC') + 2)
+        self.assertEquals(a_class_pyname, result)
+
+    def test_class_method_in_class_body_but_not_indexed(self):
+        code = 'class C(object):\n    def func(self, func):\n        pass\n'
+        scope = self.pycore.get_string_scope(code)
+        a_func_pyname = scope.get_scopes()[0].get_scopes()[0]['func']
+        name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject)
+        result = name_finder.get_pyname_at(code.index(', func') + 3)
+        self.assertEquals(a_func_pyname, result)
+
+    def test_function_but_not_indexed(self):
+        code = 'def a_func(a_func):\n    pass\n'
+        scope = self.pycore.get_string_scope(code)
+        a_func_pyname = scope['a_func']
+        name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject)
+        result = name_finder.get_pyname_at(code.index('a_func') + 3)
+        self.assertEquals(a_func_pyname, result)
+
+    def test_modules_after_from_statements(self):
+        root_folder = self.project.root
+        mod = testutils.create_module(self.project, 'mod', root_folder)
+        mod.write('def a_func():\n    pass\n')
+        code = 'from mod import a_func\n'
+        scope = self.pycore.get_string_scope(code)
+        name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject)
+        mod_pyobject = self.pycore.resource_to_pyobject(mod)
+        found_pyname = name_finder.get_pyname_at(code.index('mod') + 1)
+        self.assertEquals(mod_pyobject, found_pyname.get_object())
+
+    def test_renaming_functions_with_from_import_and_parens(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('def afunc():\n    pass\n')
+        code = 'from mod1 import (\n    afunc as func)\n'
+        scope = self.pycore.get_string_scope(code)
+        name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject)
+        mod_pyobject = self.pycore.resource_to_pyobject(mod1)
+        afunc = mod_pyobject['afunc']
+        found_pyname = name_finder.get_pyname_at(code.index('afunc') + 1)
+        self.assertEquals(afunc.get_object(), found_pyname.get_object())
+
+    @testutils.run_only_for_25
+    def test_relative_modules_after_from_statements(self):
+        pkg1 = testutils.create_package(self.project, 'pkg1')
+        pkg2 = testutils.create_package(self.project, 'pkg2', pkg1)
+        mod1 = testutils.create_module(self.project, 'mod1', pkg1)
+        mod2 = testutils.create_module(self.project, 'mod2', pkg2)
+        mod1.write('def a_func():\n    pass\n')
+        code = 'from ..mod1 import a_func\n'
+        mod2.write(code)
+        mod2_scope = self.pycore.resource_to_pyobject(mod2).get_scope()
+        name_finder = rope.base.evaluate.ScopeNameFinder(mod2_scope.pyobject)
+        mod1_pyobject = self.pycore.resource_to_pyobject(mod1)
+        found_pyname = name_finder.get_pyname_at(code.index('mod1') + 1)
+        self.assertEquals(mod1_pyobject, found_pyname.get_object())
+
+    def test_relative_modules_after_from_statements2(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        pkg1 = testutils.create_package(self.project, 'pkg1')
+        pkg2 = testutils.create_package(self.project, 'pkg2', pkg1)
+        mod2 = testutils.create_module(self.project, 'mod2', pkg2)
+        mod1.write('import pkg1.pkg2.mod2')
+
+        mod1_scope = self.pycore.resource_to_pyobject(mod1).get_scope()
+        name_finder = rope.base.evaluate.ScopeNameFinder(mod1_scope.pyobject)
+        pkg2_pyobject = self.pycore.resource_to_pyobject(pkg2)
+        found_pyname = name_finder.get_pyname_at(mod1.read().index('pkg2') + 1)
+        self.assertEquals(pkg2_pyobject, found_pyname.get_object())
+
+    @testutils.assert_raises(exceptions.RopeError)
+    def test_get_pyname_at_on_language_keywords(self):
+        code = 'def a_func(a_func):\n    pass\n'
+        pymod = self.pycore.get_string_module(code)
+        name_finder = rope.base.evaluate.ScopeNameFinder(pymod)
+        name_finder.get_pyname_at(code.index('pass'))
+
+    def test_one_liners(self):
+        code = 'var = 1\ndef f(): var = 2\nprint var\n'
+        pymod = self.pycore.get_string_module(code)
+        name_finder = rope.base.evaluate.ScopeNameFinder(pymod)
+        pyname = name_finder.get_pyname_at(code.rindex('var'))
+        self.assertEquals(pymod['var'], pyname)
+
+    def test_one_liners_with_line_breaks(self):
+        code = 'var = 1\ndef f(\n): var = 2\nprint var\n'
+        pymod = self.pycore.get_string_module(code)
+        name_finder = rope.base.evaluate.ScopeNameFinder(pymod)
+        pyname = name_finder.get_pyname_at(code.rindex('var'))
+        self.assertEquals(pymod['var'], pyname)
+
+    def test_one_liners_with_line_breaks2(self):
+        code = 'var = 1\ndef f(\np): var = 2\nprint var\n'
+        pymod = self.pycore.get_string_module(code)
+        name_finder = rope.base.evaluate.ScopeNameFinder(pymod)
+        pyname = name_finder.get_pyname_at(code.rindex('var'))
+        self.assertEquals(pymod['var'], pyname)
+
+
+class LogicalLineFinderTest(unittest.TestCase):
+
+    def setUp(self):
+        super(LogicalLineFinderTest, self).setUp()
+
+    def tearDown(self):
+        super(LogicalLineFinderTest, self).tearDown()
+
+    def _logical_finder(self, code):
+        return LogicalLineFinder(SourceLinesAdapter(code))
+
+    def test_normal_lines(self):
+        code = 'a_var = 10'
+        line_finder = self._logical_finder(code)
+        self.assertEquals((1, 1), line_finder.logical_line_in(1))
+
+    def test_normal_lines2(self):
+        code = 'another = 10\na_var = 20\n'
+        line_finder = self._logical_finder(code)
+        self.assertEquals((1, 1), line_finder.logical_line_in(1))
+        self.assertEquals((2, 2), line_finder.logical_line_in(2))
+
+    def test_implicit_continuation(self):
+        code = 'a_var = 3 + \\\n    4 + \\\n    5'
+        line_finder = self._logical_finder(code)
+        self.assertEquals((1, 3), line_finder.logical_line_in(2))
+
+    def test_explicit_continuation(self):
+        code = 'print 2\na_var = (3 + \n    4, \n    5)\n'
+        line_finder = self._logical_finder(code)
+        self.assertEquals((2, 4), line_finder.logical_line_in(2))
+
+    def test_explicit_continuation_comments(self):
+        code = '#\na_var = 3\n'
+        line_finder = self._logical_finder(code)
+        self.assertEquals((2, 2), line_finder.logical_line_in(2))
+
+    def test_multiple_indented_ifs(self):
+        code = 'if True:\n    if True:\n        if True:\n            pass\n    a = 10\n'
+        line_finder = self._logical_finder(code)
+        self.assertEquals((5, 5), line_finder.logical_line_in(5))
+
+    def test_list_comprehensions_and_fors(self):
+        code = 'a_list = [i\n    for i in range(10)]\n'
+        line_finder = self._logical_finder(code)
+        self.assertEquals((1, 2), line_finder.logical_line_in(2))
+
+    def test_generator_expressions_and_fors(self):
+        code = 'a_list = (i\n    for i in range(10))\n'
+        line_finder = self._logical_finder(code)
+        self.assertEquals((1, 2), line_finder.logical_line_in(2))
+
+    def test_fors_and_block_start(self):
+        code = 'l = range(10)\nfor i in l:\n    print i\n'
+        self.assertEquals(2, get_block_start(SourceLinesAdapter(code), 2))
+
+    def test_problems_with_inner_indentations(self):
+        code = 'if True:\n    if True:\n        if True:\n            pass\n' \
+               '    a = \\\n        1\n'
+        line_finder = self._logical_finder(code)
+        self.assertEquals((5, 6), line_finder.logical_line_in(6))
+
+    def test_problems_with_inner_indentations2(self):
+        code = 'if True:\n    if True:\n        pass\n' \
+               'a = 1\n'
+        line_finder = self._logical_finder(code)
+        self.assertEquals((4, 4), line_finder.logical_line_in(4))
+
+    def test_logical_lines_for_else(self):
+        code = 'if True:\n    pass\nelse:\n    pass\n'
+        line_finder = self._logical_finder(code)
+        self.assertEquals((3, 3), line_finder.logical_line_in(3))
+
+    def test_logical_lines_for_lines_with_wrong_continues(self):
+        code = 'var = 1 + \\'
+        line_finder = self._logical_finder(code)
+        self.assertEquals((1, 1), line_finder.logical_line_in(1))
+
+    def test_generating_line_starts(self):
+        code = 'a = 1\na = 2\n\na = 3\n'
+        line_finder = self._logical_finder(code)
+        self.assertEquals([1, 2, 4], list(line_finder.generate_starts()))
+
+    def test_generating_line_starts2(self):
+        code = 'a = 1\na = 2\n\na = \\ 3\n'
+        line_finder = LogicalLineFinder(SourceLinesAdapter(code))
+        self.assertEquals([2, 4], list(line_finder.generate_starts(2)))
+
+    def test_generating_line_starts3(self):
+        code = 'a = 1\na = 2\n\na = \\ 3\n'
+        line_finder = LogicalLineFinder(SourceLinesAdapter(code))
+        self.assertEquals([2], list(line_finder.generate_starts(2, 3)))
+
+    def test_generating_line_starts_for_multi_line_statements(self):
+        code = '\na = \\\n 1 + \\\n 1\n'
+        line_finder = self._logical_finder(code)
+        self.assertEquals([2], list(line_finder.generate_starts()))
+
+    def test_generating_line_starts_and_unmatched_deindents(self):
+        code = 'if True:\n    if True:\n        if True:\n' \
+               '            a = 1\n    b = 1\n'
+        line_finder = self._logical_finder(code)
+        self.assertEquals([4, 5], list(line_finder.generate_starts(4)))
+
+class TokenizerLogicalLineFinderTest(LogicalLineFinderTest):
+
+    def _logical_finder(self, code):
+        lines = SourceLinesAdapter(code)
+        return codeanalyze.CachingLogicalLineFinder(
+            lines, codeanalyze.tokenizer_generator)
+
+class CustomLogicalLineFinderTest(LogicalLineFinderTest):
+
+    def _logical_finder(self, code):
+        lines = SourceLinesAdapter(code)
+        return codeanalyze.CachingLogicalLineFinder(
+            lines, codeanalyze.custom_generator)
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(SourceLinesAdapterTest))
+    result.addTests(unittest.makeSuite(WordRangeFinderTest))
+    result.addTests(unittest.makeSuite(ScopeNameFinderTest))
+    result.addTests(unittest.makeSuite(LogicalLineFinderTest))
+    result.addTests(unittest.makeSuite(TokenizerLogicalLineFinderTest))
+    result.addTests(unittest.makeSuite(CustomLogicalLineFinderTest))
+    return result
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/contrib/__init__.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,32 @@
+import sys
+import unittest
+
+import ropetest.contrib.autoimporttest
+import ropetest.contrib.changestacktest
+import ropetest.contrib.codeassisttest
+import ropetest.contrib.finderrorstest
+import ropetest.contrib.findittest
+import ropetest.contrib.fixmodnamestest
+import ropetest.contrib.generatetest
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(ropetest.contrib.generatetest.
+                                       GenerateTest))
+    result.addTests(ropetest.contrib.codeassisttest.suite())
+    result.addTests(ropetest.contrib.autoimporttest.suite())
+    result.addTests(ropetest.contrib.findittest.suite())
+    result.addTests(unittest.makeSuite(ropetest.contrib.changestacktest.
+                                       ChangeStackTest))
+    result.addTests(unittest.makeSuite(ropetest.contrib.fixmodnamestest.
+                                       FixModuleNamesTest))
+    result.addTests(unittest.makeSuite(ropetest.contrib.finderrorstest.
+                                       FindErrorsTest))
+    return result
+
+
+if __name__ == '__main__':
+    runner = unittest.TextTestRunner()
+    result = runner.run(suite())
+    sys.exit(not result.wasSuccessful())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/contrib/autoimporttest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,166 @@
+import unittest
+
+from ropetest import testutils
+from rope.contrib import autoimport
+
+
+class AutoImportTest(unittest.TestCase):
+
+    def setUp(self):
+        super(AutoImportTest, self).setUp()
+        self.project = testutils.sample_project(extension_modules=['sys'])
+        self.mod1 = testutils.create_module(self.project, 'mod1')
+        self.pkg = testutils.create_package(self.project, 'pkg')
+        self.mod2 = testutils.create_module(self.project, 'mod2', self.pkg)
+        self.importer = autoimport.AutoImport(self.project, observe=False)
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(AutoImportTest, self).tearDown()
+
+    def test_simple_case(self):
+        self.assertEquals([], self.importer.import_assist('A'))
+
+    def test_update_resource(self):
+        self.mod1.write('myvar = None\n')
+        self.importer.update_resource(self.mod1)
+        self.assertEquals([('myvar', 'mod1')],
+                          self.importer.import_assist('myva'))
+
+    def test_update_module(self):
+        self.mod1.write('myvar = None')
+        self.importer.update_module('mod1')
+        self.assertEquals([('myvar', 'mod1')],
+                          self.importer.import_assist('myva'))
+
+    def test_update_non_existent_module(self):
+        self.importer.update_module('does_not_exists_this')
+        self.assertEquals([], self.importer.import_assist('myva'))
+
+    def test_module_with_syntax_errors(self):
+        self.mod1.write('this is a syntax error\n')
+        self.importer.update_resource(self.mod1)
+        self.assertEquals([], self.importer.import_assist('myva'))
+
+    def test_excluding_imported_names(self):
+        self.mod1.write('import pkg\n')
+        self.importer.update_resource(self.mod1)
+        self.assertEquals([], self.importer.import_assist('pkg'))
+
+    def test_get_modules(self):
+        self.mod1.write('myvar = None\n')
+        self.importer.update_resource(self.mod1)
+        self.assertEquals(['mod1'], self.importer.get_modules('myvar'))
+
+    def test_get_modules_inside_packages(self):
+        self.mod1.write('myvar = None\n')
+        self.mod2.write('myvar = None\n')
+        self.importer.update_resource(self.mod1)
+        self.importer.update_resource(self.mod2)
+        self.assertEquals(set(['mod1', 'pkg.mod2']),
+                          set(self.importer.get_modules('myvar')))
+
+    def test_trivial_insertion_line(self):
+        result = self.importer.find_insertion_line('')
+        self.assertEquals(1, result)
+
+    def test_insertion_line(self):
+        result = self.importer.find_insertion_line('import mod\n')
+        self.assertEquals(2, result)
+
+    def test_insertion_line_with_pydocs(self):
+        result = self.importer.find_insertion_line(
+            '"""docs\n\ndocs"""\nimport mod\n')
+        self.assertEquals(5, result)
+
+    def test_insertion_line_with_multiple_imports(self):
+        result = self.importer.find_insertion_line(
+            'import mod1\n\nimport mod2\n')
+        self.assertEquals(4, result)
+
+    def test_insertion_line_with_blank_lines(self):
+        result = self.importer.find_insertion_line(
+            'import mod1\n\n# comment\n')
+        self.assertEquals(2, result)
+
+    def test_empty_cache(self):
+        self.mod1.write('myvar = None\n')
+        self.importer.update_resource(self.mod1)
+        self.assertEquals(['mod1'], self.importer.get_modules('myvar'))
+        self.importer.clear_cache()
+        self.assertEquals([], self.importer.get_modules('myvar'))
+
+    def test_not_caching_underlined_names(self):
+        self.mod1.write('_myvar = None\n')
+        self.importer.update_resource(self.mod1, underlined=False)
+        self.assertEquals([], self.importer.get_modules('_myvar'))
+        self.importer.update_resource(self.mod1, underlined=True)
+        self.assertEquals(['mod1'], self.importer.get_modules('_myvar'))
+
+    def test_caching_underlined_names_passing_to_the_constructor(self):
+        importer = autoimport.AutoImport(self.project, False, True)
+        self.mod1.write('_myvar = None\n')
+        importer.update_resource(self.mod1)
+        self.assertEquals(['mod1'], importer.get_modules('_myvar'))
+
+    def test_name_locations(self):
+        self.mod1.write('myvar = None\n')
+        self.importer.update_resource(self.mod1)
+        self.assertEquals([(self.mod1, 1)],
+                          self.importer.get_name_locations('myvar'))
+
+    def test_name_locations_with_multiple_occurrences(self):
+        self.mod1.write('myvar = None\n')
+        self.mod2.write('\nmyvar = None\n')
+        self.importer.update_resource(self.mod1)
+        self.importer.update_resource(self.mod2)
+        self.assertEquals(set([(self.mod1, 1), (self.mod2, 2)]),
+                          set(self.importer.get_name_locations('myvar')))
+
+    def test_handling_builtin_modules(self):
+        self.importer.update_module('sys')
+        self.assertTrue('sys' in self.importer.get_modules('exit'))
+
+    def test_submodules(self):
+        self.assertEquals(set([self.mod1]),
+                          autoimport.submodules(self.mod1))
+        self.assertEquals(set([self.mod2, self.pkg]),
+                          autoimport.submodules(self.pkg))
+
+class AutoImportObservingTest(unittest.TestCase):
+
+    def setUp(self):
+        super(AutoImportObservingTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.mod1 = testutils.create_module(self.project, 'mod1')
+        self.pkg = testutils.create_package(self.project, 'pkg')
+        self.mod2 = testutils.create_module(self.project, 'mod2', self.pkg)
+        self.importer = autoimport.AutoImport(self.project, observe=True)
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(AutoImportObservingTest, self).tearDown()
+
+    def test_writing_files(self):
+        self.mod1.write('myvar = None\n')
+        self.assertEquals(['mod1'], self.importer.get_modules('myvar'))
+
+    def test_moving_files(self):
+        self.mod1.write('myvar = None\n')
+        self.mod1.move('mod3.py')
+        self.assertEquals(['mod3'], self.importer.get_modules('myvar'))
+
+    def test_removing_files(self):
+        self.mod1.write('myvar = None\n')
+        self.mod1.remove()
+        self.assertEquals([], self.importer.get_modules('myvar'))
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(AutoImportTest))
+    result.addTests(unittest.makeSuite(AutoImportObservingTest))
+    return result
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/contrib/changestacktest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,35 @@
+import unittest
+
+import rope.base.history
+import rope.contrib.changestack
+from rope.base.change import *
+from ropetest import testutils
+
+
+class ChangeStackTest(unittest.TestCase):
+
+    def setUp(self):
+        super(ChangeStackTest, self).setUp()
+        self.project = testutils.sample_project()
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(ChangeStackTest, self).tearDown()
+
+    def test_change_stack(self):
+        myfile = self.project.root.create_file('myfile.txt')
+        myfile.write('1')
+        stack = rope.contrib.changestack.ChangeStack(self.project)
+        stack.push(ChangeContents(myfile, '2'))
+        self.assertEquals('2', myfile.read())
+        stack.push(ChangeContents(myfile, '3'))
+        self.assertEquals('3', myfile.read())
+        stack.pop_all()
+        self.assertEquals('1', myfile.read())
+        changes = stack.merged()
+        self.project.do(changes)
+        self.assertEquals('3', myfile.read())
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/contrib/codeassisttest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,1065 @@
+# coding: utf-8
+import unittest
+
+from rope.base import exceptions
+from rope.contrib.codeassist import (get_definition_location, get_doc,
+                                     starting_expression, code_assist,
+                                     sorted_proposals, starting_offset,
+                                     get_calltip)
+from ropetest import testutils
+
+
+class CodeAssistTest(unittest.TestCase):
+
+    def setUp(self):
+        super(CodeAssistTest, self).setUp()
+        self.project = testutils.sample_project()
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(CodeAssistTest, self).tearDown()
+
+    def _assist(self, code, offset=None, **args):
+        if offset is None:
+            offset = len(code)
+        return code_assist(self.project, code, offset,  **args)
+
+    def test_simple_assist(self):
+        self._assist('', 0)
+
+    def assert_completion_in_result(self, name, scope, result, type=None):
+        for proposal in result:
+            if proposal.name == name:
+                self.assertEqual(scope, proposal.scope,
+                        "proposal <%s> has wrong scope, expected " \
+                        "%r, got %r" % (name, scope, proposal.scope))
+                if type is not None:
+                    self.assertEqual(type, proposal.type,
+                            "proposal <%s> has wrong type, expected " \
+                            "%r, got %r" % (name, type, proposal.type))
+                return
+        self.fail('completion <%s> not proposed' % name)
+
+    def assert_completion_not_in_result(self, name, scope, result):
+        for proposal in result:
+            if proposal.name == name and proposal.scope == scope:
+                self.fail('completion <%s> was proposed' % name)
+
+    def test_completing_global_variables(self):
+        code = 'my_global = 10\nt = my'
+        result = self._assist(code)
+        self.assert_completion_in_result('my_global', 'global', result)
+
+    def test_not_proposing_unmatched_vars(self):
+        code = 'my_global = 10\nt = you'
+        result = self._assist(code)
+        self.assert_completion_not_in_result('my_global', 'global', result)
+
+    def test_not_proposing_unmatched_vars_with_underlined_starting(self):
+        code = 'my_global = 10\nt = your_'
+        result = self._assist(code)
+        self.assert_completion_not_in_result('my_global', 'global', result)
+
+    def test_not_proposing_local_assigns_as_global_completions(self):
+        code = 'def f():    my_global = 10\nt = my_'
+        result = self._assist(code)
+        self.assert_completion_not_in_result('my_global', 'global', result)
+
+    def test_proposing_functions(self):
+        code = 'def my_func():    return 2\nt = my_'
+        result = self._assist(code)
+        self.assert_completion_in_result('my_func', 'global', result)
+
+    def test_proposing_classes(self):
+        code = 'class Sample(object):    pass\nt = Sam'
+        result = self._assist(code)
+        self.assert_completion_in_result('Sample', 'global', result)
+
+    def test_proposing_each_name_at_most_once(self):
+        code = 'variable = 10\nvariable = 20\nt = vari'
+        result = self._assist(code)
+        count = len([x for x in result
+                     if x.name == 'variable' and x.scope == 'global'])
+        self.assertEquals(1, count)
+
+    @testutils.assert_raises(exceptions.ModuleSyntaxError)
+    def test_throwing_exception_in_case_of_syntax_errors(self):
+        code = 'sample (sdf+)\n'
+        self._assist(code, maxfixes=0)
+
+    def test_fixing_errors_with_maxfixes(self):
+        code = 'def f():\n    sldj sldj\ndef g():\n    ran'
+        result = self._assist(code, maxfixes=2)
+        self.assertTrue(len(result) > 0)
+
+    def test_ignoring_errors_in_current_line(self):
+        code = 'def my_func():\n    return 2\nt = '
+        result = self._assist(code)
+        self.assert_completion_in_result('my_func', 'global', result)
+
+    def test_not_reporting_variables_in_current_line(self):
+        code = 'def my_func():    return 2\nt = my_'
+        result = self._assist(code)
+        self.assert_completion_not_in_result('my_', 'global', result)
+
+    def test_completion_result(self):
+        code = 'my_global = 10\nt = my'
+        self.assertEquals(len(code) - 2, starting_offset(code, len(code)))
+
+    def test_completing_imported_names(self):
+        code = 'import sys\na = sy'
+        result = self._assist(code)
+        self.assert_completion_in_result('sys', 'imported', result)
+
+    def test_completing_imported_names_with_as(self):
+        code = 'import sys as mysys\na = mys'
+        result = self._assist(code)
+        self.assert_completion_in_result('mysys', 'imported', result)
+
+    def test_not_completing_imported_names_with_as(self):
+        code = 'import sys as mysys\na = sy'
+        result = self._assist(code)
+        self.assert_completion_not_in_result('sys', 'global', result)
+
+    def test_including_matching_builtins_types(self):
+        code = 'my_var = Excep'
+        result = self._assist(code)
+        self.assert_completion_in_result('Exception', 'builtin', result)
+        self.assert_completion_not_in_result('zip', 'builtin', result)
+
+    def test_including_matching_builtins_functions(self):
+        code = 'my_var = zi'
+        result = self._assist(code)
+        self.assert_completion_in_result('zip', 'builtin', result)
+
+    def test_builtin_instances(self):
+        # ``import_dynload_stdmods`` pref is disabled for test project.
+        # we need to have it enabled to make pycore._find_module()
+        # load ``sys`` module.
+        self.project.prefs['import_dynload_stdmods'] = True
+        code = 'from sys import stdout\nstdout.wr'
+        result = self._assist(code)
+        self.assert_completion_in_result('write', 'builtin', result)
+        self.assert_completion_in_result('writelines', 'builtin', result)
+
+    def test_including_keywords(self):
+        code = 'fo'
+        result = self._assist(code)
+        self.assert_completion_in_result('for', 'keyword', result)
+
+    def test_not_reporting_proposals_after_dot(self):
+        code = 'a_dict = {}\nkey = 3\na_dict.ke'
+        result = self._assist(code)
+        self.assert_completion_not_in_result('key', 'global', result)
+
+    def test_proposing_local_variables_in_functions(self):
+        code = 'def f(self):\n    my_var = 10\n    my_'
+        result = self._assist(code)
+        self.assert_completion_in_result('my_var', 'local', result)
+
+    def test_local_variables_override_global_ones(self):
+        code = 'my_var = 20\ndef f(self):\n    my_var = 10\n    my_'
+        result = self._assist(code)
+        self.assert_completion_in_result('my_var', 'local', result)
+
+    def test_not_including_class_body_variables(self):
+        code = 'class C(object):\n    my_var = 20\n' \
+               '    def f(self):\n        a = 20\n        my_'
+        result = self._assist(code)
+        self.assert_completion_not_in_result('my_var', 'local', result)
+
+    def test_nested_functions(self):
+        code = 'def my_func():\n    func_var = 20\n    ' \
+               'def inner_func():\n        a = 20\n        func'
+        result = self._assist(code)
+        self.assert_completion_in_result('func_var', 'local', result)
+
+    def test_scope_endpoint_selection(self):
+        code = "def my_func():\n    func_var = 20\n"
+        result = self._assist(code)
+        self.assert_completion_not_in_result('func_var', 'local', result)
+
+    def test_scope_better_endpoint_selection(self):
+        code = "if True:\n    def f():\n        my_var = 10\n    my_"
+        result = self._assist(code)
+        self.assert_completion_not_in_result('my_var', 'local', result)
+
+    def test_imports_inside_function(self):
+        code = "def f():\n    import sys\n    sy"
+        result = self._assist(code)
+        self.assert_completion_in_result('sys', 'imported', result)
+
+    def test_imports_inside_function_dont_mix_with_globals(self):
+        code = "def f():\n    import sys\nsy"
+        result = self._assist(code)
+        self.assert_completion_not_in_result('sys', 'local', result)
+
+    def test_nested_classes_local_names(self):
+        code = 'global_var = 10\n' \
+               'def my_func():\n' \
+               '    func_var = 20\n' \
+               '    class C(object):\n' \
+               '        def another_func(self):\n' \
+               '            local_var = 10\n' \
+               '            func'
+        result = self._assist(code)
+        self.assert_completion_in_result('func_var', 'local', result)
+
+    def test_nested_classes_global(self):
+        code = 'global_var = 10\n' \
+               'def my_func():\n' \
+               '    func_var = 20\n' \
+               '    class C(object):\n' \
+               '        def another_func(self):\n' \
+               '            local_var = 10\n' \
+               '            globa'
+        result = self._assist(code)
+        self.assert_completion_in_result('global_var', 'global', result)
+
+    def test_nested_classes_global_function(self):
+        code = 'global_var = 10\n' \
+               'def my_func():\n' \
+               '    func_var = 20\n' \
+               '    class C(object):\n' \
+               '        def another_func(self):\n' \
+               '            local_var = 10\n' \
+               '            my_f'
+        result = self._assist(code)
+        self.assert_completion_in_result('my_func', 'global', result)
+
+    def test_proposing_function_parameters_in_functions(self):
+        code = 'def my_func(my_param):\n    my_var = 20\n    my_'
+        result = self._assist(code)
+        self.assert_completion_in_result('my_param', 'local', result)
+
+    def test_proposing_function_keyword_parameters_in_functions(self):
+        code = 'def my_func(my_param, *my_list, **my_kws):\n' \
+               '    my_var = 20\n' \
+               '    my_'
+        result = self._assist(code)
+        self.assert_completion_in_result('my_param', 'local', result)
+        self.assert_completion_in_result('my_list', 'local', result)
+        self.assert_completion_in_result('my_kws', 'local', result)
+
+    def test_not_proposing_unmatching_function_parameters_in_functions(self):
+        code = "def my_func(my_param):\n    my_var = 20\n    you_"
+        result = self._assist(code)
+        self.assert_completion_not_in_result('my_param', 'local', result)
+
+    def test_ignoring_current_statement(self):
+        code = "my_var = 10\nmy_tuple = (10, \n           my_"
+        result = self._assist(code)
+        self.assert_completion_in_result('my_var', 'global', result)
+
+    def test_ignoring_current_statement_brackets_continuation(self):
+        code = "my_var = 10\n'hello'[10:\n        my_"
+        result = self._assist(code)
+        self.assert_completion_in_result('my_var', 'global', result)
+
+    def test_ignoring_current_statement_explicit_continuation(self):
+        code = "my_var = 10\nmy_var2 = 2 + \\\n          my_"
+        result = self._assist(code)
+        self.assert_completion_in_result('my_var', 'global', result)
+
+    def test_ignoring_current_statement_while_the_first_statement_of_the_block(self):
+        code = "my_var = 10\ndef f():\n    my_"
+        result = self._assist(code)
+        self.assert_completion_in_result('my_var', 'global', result)
+
+    def test_ignoring_current_statement_while_current_line_ends_with_a_colon(self):
+        code = "my_var = 10\nif my_:\n    pass"
+        result = self._assist(code, 18)
+        self.assert_completion_in_result('my_var', 'global', result)
+
+    def test_ignoring_string_contents(self):
+        code = "my_var = '('\nmy_"
+        result = self._assist(code)
+        self.assert_completion_in_result('my_var', 'global', result)
+
+    def test_ignoring_comment_contents(self):
+        code = "my_var = 10 #(\nmy_"
+        result = self._assist(code)
+        self.assert_completion_in_result('my_var', 'global', result)
+
+    def test_ignoring_string_contents_backslash_plus_quotes(self):
+        code = "my_var = '\\''\nmy_"
+        result = self._assist(code)
+        self.assert_completion_in_result('my_var', 'global', result)
+
+    def test_ignoring_string_contents_backslash_plus_backslash(self):
+        code = "my_var = '\\\\'\nmy_"
+        result = self._assist(code)
+        self.assert_completion_in_result('my_var', 'global', result)
+
+    def test_not_proposing_later_defined_variables_in_current_block(self):
+        code = "my_\nmy_var = 10\n"
+        result = self._assist(code, 3, later_locals=False)
+        self.assert_completion_not_in_result('my_var', 'global', result)
+
+    def test_not_proposing_later_defined_variables_in_current_function(self):
+        code = "def f():\n    my_\n    my_var = 10\n"
+        result = self._assist(code, 16, later_locals=False)
+        self.assert_completion_not_in_result('my_var', 'local', result)
+
+    def test_ignoring_string_contents_with_triple_quotes(self):
+        code = "my_var = '''(\n'('''\nmy_"
+        result = self._assist(code)
+        self.assert_completion_in_result('my_var', 'global', result)
+
+    def test_ignoring_string_contents_with_triple_quotes_and_backslash(self):
+        code = 'my_var = """\\"""("""\nmy_'
+        result = self._assist(code)
+        self.assert_completion_in_result('my_var', 'global', result)
+
+    def test_ignoring_string_contents_with_triple_quotes_and_double_backslash(self):
+        code = 'my_var = """\\\\"""\nmy_'
+        result = self._assist(code)
+        self.assert_completion_in_result('my_var', 'global', result)
+
+    def test_reporting_params_when_in_the_first_line_of_a_function(self):
+        code = 'def f(param):\n    para'
+        result = self._assist(code)
+        self.assert_completion_in_result('param', 'local', result)
+
+    def test_code_assist_when_having_a_two_line_function_header(self):
+        code = 'def f(param1,\n      param2):\n    para'
+        result = self._assist(code)
+        self.assert_completion_in_result('param1', 'local', result)
+
+    def test_code_assist_with_function_with_two_line_return(self):
+        code = 'def f(param1, param2):\n    return(param1,\n           para'
+        result = self._assist(code)
+        self.assert_completion_in_result('param2', 'local', result)
+
+    def test_get_definition_location(self):
+        code = 'def a_func():\n    pass\na_func()'
+        result = get_definition_location(self.project, code, len(code) - 3)
+        self.assertEquals((None, 1), result)
+
+    def test_get_definition_location_underlined_names(self):
+        code = 'def a_sample_func():\n    pass\na_sample_func()'
+        result = get_definition_location(self.project, code, len(code) - 11)
+        self.assertEquals((None, 1), result)
+
+    def test_get_definition_location_dotted_names(self):
+        code = 'class AClass(object):\n' \
+               '    @staticmethod\n' \
+               '    def a_method():\n' \
+               '        pass\n' \
+               'AClass.a_method()'
+        result = get_definition_location(self.project, code, len(code) - 3)
+        self.assertEquals((None, 2), result)
+
+    def test_get_definition_location_dotted_module_names(self):
+        module_resource = testutils.create_module(self.project, 'mod')
+        module_resource.write('def a_func():\n    pass\n')
+        code = 'import mod\nmod.a_func()'
+        result = get_definition_location(self.project, code, len(code) - 3)
+        self.assertEquals((module_resource, 1), result)
+
+    def test_get_definition_location_for_nested_packages(self):
+        pycore = self.project.pycore
+        mod1 = testutils.create_module(self.project, 'mod1')
+        pkg1 = testutils.create_package(self.project, 'pkg1')
+        pkg2 = testutils.create_package(self.project, 'pkg2', pkg1)
+        mod2 = testutils.create_module(self.project, 'mod2', pkg2)
+        mod1.write('import pkg1.pkg2.mod2')
+
+        mod1_scope = pycore.resource_to_pyobject(mod1).get_scope()
+        init_dot_py = pkg2.get_child('__init__.py')
+        found_pyname = get_definition_location(self.project, mod1.read(),
+                                               mod1.read().index('pkg2') + 1)
+        self.assertEquals(init_dot_py, found_pyname[0])
+
+    def test_get_definition_location_unknown(self):
+        code = 'a_func()\n'
+        result = get_definition_location(self.project, code, len(code) - 3)
+        self.assertEquals((None, None), result)
+
+    def test_get_definition_location_dot_spaces(self):
+        code = 'class AClass(object):\n    ' \
+               '@staticmethod\n    def a_method():\n' \
+               '        pass\nAClass.\\\n     a_method()'
+        result = get_definition_location(self.project, code, len(code) - 3)
+        self.assertEquals((None, 2), result)
+
+    def test_get_definition_location_dot_line_break_inside_parens(self):
+        code = 'class A(object):\n    def a_method(self):\n        pass\n' + \
+               '(A.\na_method)'
+        result = get_definition_location(self.project, code,
+                                         code.rindex('a_method') + 1)
+        self.assertEquals((None, 2), result)
+
+    def test_if_scopes_in_other_scopes_for_get_definition_location(self):
+        code = 'def f(a_var):\n    pass\na_var = 10\nif True:\n    print a_var\n'
+        result = get_definition_location(self.project, code, len(code) - 3)
+        self.assertEquals((None, 3), result)
+
+    def test_code_assists_in_parens(self):
+        code = 'def a_func(a_var):\n    pass\na_var = 10\na_func(a_'
+        result = self._assist(code)
+        self.assert_completion_in_result('a_var', 'global', result)
+
+    def test_simple_type_inferencing(self):
+        code = 'class Sample(object):\n' \
+               '    def __init__(self, a_param):\n' \
+               '        pass\n' \
+               '    def a_method(self):\n' \
+               '        pass\n' \
+               'Sample("hey").a_'
+        result = self._assist(code)
+        self.assert_completion_in_result('a_method', 'attribute', result)
+
+    def test_proposals_sorter(self):
+        code = 'def my_sample_function(self):\n' + \
+               '    my_sample_var = 20\n' + \
+               '    my_sample_'
+        proposals = sorted_proposals(self._assist(code))
+        self.assertEquals('my_sample_var', proposals[0].name)
+        self.assertEquals('my_sample_function', proposals[1].name)
+
+    def test_proposals_sorter_for_methods_and_attributes(self):
+        code = 'class A(object):\n' + \
+               '    def __init__(self):\n' + \
+               '        self.my_a_var = 10\n' + \
+               '    def my_b_func(self):\n' + \
+               '        pass\n' + \
+               '    def my_c_func(self):\n' + \
+               '        pass\n' + \
+               'a_var = A()\n' + \
+               'a_var.my_'
+        proposals = sorted_proposals(self._assist(code))
+        self.assertEquals('my_b_func', proposals[0].name)
+        self.assertEquals('my_c_func', proposals[1].name)
+        self.assertEquals('my_a_var', proposals[2].name)
+
+    def test_proposals_sorter_for_global_methods_and_funcs(self):
+        code = 'def my_b_func(self):\n' + \
+               '    pass\n' + \
+               'my_a_var = 10\n' + \
+               'my_'
+        proposals = sorted_proposals(self._assist(code))
+        self.assertEquals('my_b_func', proposals[0].name)
+        self.assertEquals('my_a_var', proposals[1].name)
+
+    def test_proposals_sorter_underlined_methods(self):
+        code = 'class A(object):\n' + \
+               '    def _my_func(self):\n' + \
+               '        self.my_a_var = 10\n' + \
+               '    def my_func(self):\n' + \
+               '        pass\n' + \
+               'a_var = A()\n' + \
+               'a_var.'
+        proposals = sorted_proposals(self._assist(code))
+        self.assertEquals('my_func', proposals[0].name)
+        self.assertEquals('_my_func', proposals[1].name)
+
+    def test_proposals_sorter_and_scope_prefs(self):
+        code = 'my_global_var = 1\n' \
+               'def func(self):\n' \
+               '    my_local_var = 2\n' \
+               '    my_'
+        result = self._assist(code)
+        proposals = sorted_proposals(result, scopepref=['global', 'local'])
+        self.assertEquals('my_global_var', proposals[0].name)
+        self.assertEquals('my_local_var', proposals[1].name)
+
+    def test_proposals_sorter_and_type_prefs(self):
+        code = 'my_global_var = 1\n' \
+               'def my_global_func(self):\n' \
+               '    pass\n' \
+               'my_'
+        result = self._assist(code)
+        proposals = sorted_proposals(result, typepref=['instance', 'function'])
+        self.assertEquals('my_global_var', proposals[0].name)
+        self.assertEquals('my_global_func', proposals[1].name)
+
+    def test_proposals_sorter_and_missing_type_in_typepref(self):
+        code = 'my_global_var = 1\n' \
+               'def my_global_func():\n' \
+               '    pass\n' \
+               'my_'
+        result = self._assist(code)
+        proposals = sorted_proposals(result, typepref=['function'])
+
+    def test_get_pydoc_unicode(self):
+        src = u'# coding: utf-8\ndef foo():\n  u"юникод-объект"'
+        doc = get_doc(self.project, src, src.index('foo') + 1)
+        self.assertTrue(isinstance(doc, unicode))
+        self.assertTrue(u'юникод-объект' in doc)
+
+    def test_get_pydoc_utf8_bytestring(self):
+        src = u'# coding: utf-8\ndef foo():\n  "байтстринг"'
+        doc = get_doc(self.project, src, src.index('foo') + 1)
+        self.assertTrue(isinstance(doc, unicode))
+        self.assertTrue(u'байтстринг' in doc)
+
+    def test_get_pydoc_for_functions(self):
+        src = 'def a_func():\n' \
+              '    """a function"""\n' \
+              '    a_var = 10\n' \
+              'a_func()'
+        self.assertTrue(get_doc(self.project, src, len(src) - 4).
+                        endswith('a function'))
+        get_doc(self.project, src, len(src) - 4).index('a_func()')
+
+    def test_get_pydoc_for_classes(self):
+        src = 'class AClass(object):\n    pass\n'
+        get_doc(self.project, src, src.index('AClass') + 1).index('AClass')
+
+    def test_get_pydoc_for_classes_with_init(self):
+        src = 'class AClass(object):\n    def __init__(self):\n        pass\n'
+        get_doc(self.project, src, src.index('AClass') + 1).index('AClass')
+
+    def test_get_pydoc_for_modules(self):
+        pycore = self.project.pycore
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('"""a module"""\n')
+        src = 'import mod\nmod'
+        self.assertEquals('a module', get_doc(self.project, src, len(src) - 1))
+
+    def test_get_pydoc_for_builtins(self):
+        src = 'print(object)\n'
+        self.assertTrue(get_doc(self.project, src,
+                                src.index('obj')) is not None)
+
+    def test_get_pydoc_for_methods_should_include_class_name(self):
+        src = 'class AClass(object):\n' \
+              '    def a_method(self):\n'\
+              '        """hey"""\n' \
+              '        pass\n'
+        doc = get_doc(self.project, src, src.index('a_method') + 1)
+        doc.index('AClass.a_method')
+        doc.index('hey')
+
+    def test_get_pydoc_for_methods_should_include_methods_from_super_classes(self):
+        src = 'class A(object):\n' \
+              '    def a_method(self):\n' \
+              '        """hey1"""\n' \
+              '        pass\n' \
+              'class B(A):\n' \
+              '    def a_method(self):\n' \
+              '        """hey2"""\n' \
+              '        pass\n'
+        doc = get_doc(self.project, src, src.rindex('a_method') + 1)
+        doc.index('A.a_method')
+        doc.index('hey1')
+        doc.index('B.a_method')
+        doc.index('hey2')
+
+    def test_get_pydoc_for_classes_should_name_super_classes(self):
+        src = 'class A(object):\n    pass\n' \
+              'class B(A):\n    pass\n'
+        doc = get_doc(self.project, src, src.rindex('B') + 1)
+        doc.index('B(A)')
+
+    def test_get_pydoc_for_builtin_functions(self):
+        src = 's = "hey"\ns.replace\n'
+        doc = get_doc(self.project, src, src.rindex('replace') + 1)
+        self.assertTrue(doc is not None)
+
+    def test_commenting_errors_before_offset(self):
+        src = 'lsjd lsjdf\ns = "hey"\ns.replace()\n'
+        doc = get_doc(self.project, src, src.rindex('replace') + 1)
+
+    def test_proposing_variables_defined_till_the_end_of_scope(self):
+        code = 'if True:\n    a_v\na_var = 10\n'
+        result = self._assist(code, code.index('a_v') + 3)
+        self.assert_completion_in_result('a_var', 'global', result)
+
+    def test_completing_in_uncomplete_try_blocks(self):
+        code = 'try:\n    a_var = 10\n    a_'
+        result = self._assist(code)
+        self.assert_completion_in_result('a_var', 'global', result)
+
+    def test_completing_in_uncomplete_try_blocks_in_functions(self):
+        code = 'def a_func():\n    try:\n        a_var = 10\n        a_'
+        result = self._assist(code)
+        self.assert_completion_in_result('a_var', 'local', result)
+
+    def test_already_complete_try_blocks_with_finally(self):
+        code = 'def a_func():\n    try:\n        a_var = 10\n        a_'
+        result = self._assist(code)
+        self.assert_completion_in_result('a_var', 'local', result)
+
+    def test_already_complete_try_blocks_with_finally2(self):
+        code = 'try:\n    a_var = 10\n    a_\nfinally:\n    pass\n'
+        result = self._assist(code, code.rindex('a_') + 2)
+        self.assert_completion_in_result('a_var', 'global', result)
+
+    def test_already_complete_try_blocks_with_except(self):
+        code = 'try:\n    a_var = 10\n    a_\nexcept Exception:\n    pass\n'
+        result = self._assist(code, code.rindex('a_') + 2)
+        self.assert_completion_in_result('a_var', 'global', result)
+
+    def test_already_complete_try_blocks_with_except2(self):
+        code = 'a_var = 10\ntry:\n    another_var = a_\n    another_var = 10\n' \
+               'except Exception:\n    pass\n'
+        result = self._assist(code, code.rindex('a_') + 2)
+        self.assert_completion_in_result('a_var', 'global', result)
+
+    def test_completing_ifs_in_uncomplete_try_blocks(self):
+        code = 'try:\n    if True:\n        a_var = 10\n    a_'
+        result = self._assist(code)
+        self.assert_completion_in_result('a_var', 'global', result)
+
+    def test_completing_ifs_in_uncomplete_try_blocks2(self):
+        code = 'try:\n    if True:\n        a_var = 10\n        a_'
+        result = self._assist(code)
+        self.assert_completion_in_result('a_var', 'global', result)
+
+    def test_completing_excepts_in_uncomplete_try_blocks(self):
+        code = 'try:\n    pass\nexcept Exc'
+        result = self._assist(code)
+        self.assert_completion_in_result('Exception', 'builtin', result)
+
+    def test_and_normal_complete_blocks_and_single_fixing(self):
+        code = 'try:\n    range.\nexcept:\n    pass\n'
+        result = self._assist(code, code.index('.'), maxfixes=1)
+
+    def test_nested_blocks(self):
+        code = 'a_var = 10\ntry:\n    try:\n        a_v'
+        result = self._assist(code)
+        self.assert_completion_in_result('a_var', 'global', result)
+
+    def test_proposing_function_keywords_when_calling(self):
+        code = 'def f(p):\n    pass\nf(p'
+        result = self._assist(code)
+        self.assert_completion_in_result('p=', 'parameter_keyword', result)
+
+    def test_proposing_function_keywords_when_calling_for_non_functions(self):
+        code = 'f = 1\nf(p'
+        result = self._assist(code)
+
+    def test_proposing_function_keywords_when_calling_extra_spaces(self):
+        code = 'def f(p):\n    pass\nf( p'
+        result = self._assist(code)
+        self.assert_completion_in_result('p=', 'parameter_keyword', result)
+
+    def test_proposing_function_keywords_when_calling_on_second_argument(self):
+        code = 'def f(p1, p2):\n    pass\nf(1, p'
+        result = self._assist(code)
+        self.assert_completion_in_result('p2=', 'parameter_keyword', result)
+
+    def test_proposing_function_keywords_when_calling_not_proposing_args(self):
+        code = 'def f(p1, *args):\n    pass\nf(1, a'
+        result = self._assist(code)
+        self.assert_completion_not_in_result('args=', 'parameter_keyword', result)
+
+    def test_proposing_function_keywords_when_calling_with_no_nothing_after_parens(self):
+        code = 'def f(p):\n    pass\nf('
+        result = self._assist(code)
+        self.assert_completion_in_result('p=', 'parameter_keyword', result)
+
+    def test_proposing_function_keywords_when_calling_with_no_nothing_after_parens2(self):
+        code = 'def f(p):\n    pass\ndef g():\n    h = f\n    f('
+        result = self._assist(code)
+        self.assert_completion_in_result('p=', 'parameter_keyword', result)
+
+    def test_codeassists_before_opening_of_parens(self):
+        code = 'def f(p):\n    pass\na_var = 1\nf(1)\n'
+        result = self._assist(code, code.rindex('f') + 1)
+        self.assert_completion_not_in_result('a_var', 'global', result)
+
+    def test_codeassist_before_single_line_indents(self):
+        code = 'myvar = 1\nif True:\n    (myv\nif True:\n    pass\n'
+        result = self._assist(code, code.rindex('myv') + 3)
+        self.assert_completion_not_in_result('myvar', 'local', result)
+
+    def test_codeassist_before_line_indents_in_a_blank_line(self):
+        code = 'myvar = 1\nif True:\n    \nif True:\n    pass\n'
+        result = self._assist(code, code.rindex('    ') + 4)
+        self.assert_completion_not_in_result('myvar', 'local', result)
+
+    def test_simple_get_calltips(self):
+        src = 'def f():\n    pass\nvar = f()\n'
+        doc = get_calltip(self.project, src, src.rindex('f'))
+        self.assertEquals('f()', doc)
+
+    def test_get_calltips_for_classes(self):
+        src = 'class C(object):\n' \
+              '    def __init__(self):\n        pass\nC('
+        doc = get_calltip(self.project, src, len(src) - 1)
+        self.assertEquals('C.__init__(self)', doc)
+
+    def test_get_calltips_for_objects_with_call(self):
+        src = 'class C(object):\n' \
+              '    def __call__(self, p):\n        pass\n' \
+              'c = C()\nc(1,'
+        doc = get_calltip(self.project, src, src.rindex('c'))
+        self.assertEquals('C.__call__(self, p)', doc)
+
+    def test_get_calltips_and_including_module_name(self):
+        src = 'class C(object):\n' \
+              '    def __call__(self, p):\n        pass\n' \
+              'c = C()\nc(1,'
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write(src)
+        doc = get_calltip(self.project, src, src.rindex('c'), mod)
+        self.assertEquals('mod.C.__call__(self, p)', doc)
+
+    def test_get_calltips_and_including_module_name(self):
+        src = 'range()\n'
+        doc = get_calltip(self.project, src, 1, ignore_unknown=True)
+        self.assertTrue(doc is None)
+
+    def test_removing_self_parameter(self):
+        src = 'class C(object):\n' \
+              '    def f(self):\n'\
+              '        pass\n' \
+              'C().f()'
+        doc = get_calltip(self.project, src, src.rindex('f'), remove_self=True)
+        self.assertEquals('C.f()', doc)
+
+    def test_removing_self_parameter_and_more_than_one_parameter(self):
+        src = 'class C(object):\n' \
+              '    def f(self, p1):\n'\
+              '        pass\n' \
+              'C().f()'
+        doc = get_calltip(self.project, src, src.rindex('f'), remove_self=True)
+        self.assertEquals('C.f(p1)', doc)
+
+    def test_lambda_calltip(self):
+        src = 'foo = lambda x, y=1: None\n' \
+              'foo()'
+        doc = get_calltip(self.project, src, src.rindex('f'))
+        self.assertEqual(doc, 'lambda(x, y)')
+
+    def test_keyword_before_parens(self):
+        code = 'if (1).:\n pass'
+        result = self._assist(code, offset=len('if (1).'))
+        self.assertTrue(result)
+
+    # TESTING PROPOSAL'S KINDS AND TYPES.
+    # SEE RELATION MATRIX IN `CompletionProposal`'s DOCSTRING
+
+    def test_local_variable_completion_proposal(self):
+        code = 'def foo():\n  xvar = 5\n  x'
+        result = self._assist(code)
+        self.assert_completion_in_result('xvar', 'local', result, 'instance')
+
+    def test_global_variable_completion_proposal(self):
+        code = 'yvar = 5\ny'
+        result = self._assist(code)
+        self.assert_completion_in_result('yvar', 'global', result, 'instance')
+
+    def test_builtin_variable_completion_proposal(self):
+        for varname in ('False', 'True'):
+            result = self._assist(varname[0])
+            self.assert_completion_in_result(varname, 'builtin', result,
+                                             type='instance')
+
+    def test_attribute_variable_completion_proposal(self):
+        code = 'class AClass(object):\n  def foo(self):\n    ' \
+               'self.bar = 1\n    self.b'
+        result = self._assist(code)
+        self.assert_completion_in_result('bar', 'attribute', result,
+                                         type='instance')
+
+    def test_local_class_completion_proposal(self):
+        code = 'def foo():\n  class LocalClass(object): pass\n  Lo'
+        result = self._assist(code)
+        self.assert_completion_in_result('LocalClass', 'local', result,
+                                         type='class')
+
+    def test_global_class_completion_proposal(self):
+        code = 'class GlobalClass(object): pass\nGl'
+        result = self._assist(code)
+        self.assert_completion_in_result('GlobalClass', 'global', result,
+                                         type='class')
+
+    def test_builtin_class_completion_proposal(self):
+        for varname in ('object', 'dict', 'file'):
+            result = self._assist(varname[0])
+            self.assert_completion_in_result(varname, 'builtin', result,
+                                             type='class')
+
+    def test_attribute_class_completion_proposal(self):
+        code = 'class Outer(object):\n  class Inner(object): pass\nOuter.'
+        result = self._assist(code)
+        self.assert_completion_in_result('Inner', 'attribute', result,
+                                         type='class')
+
+    def test_local_function_completion_proposal(self):
+        code = 'def outer():\n  def inner(): pass\n  in'
+        result = self._assist(code)
+        self.assert_completion_in_result('inner', 'local', result,
+                                         type='function')
+
+    def test_global_function_completion_proposal(self):
+        code = 'def foo(): pass\nf'
+        result = self._assist(code)
+        self.assert_completion_in_result('foo', 'global', result,
+                                         type='function')
+
+    def test_builtin_function_completion_proposal(self):
+        code = 'a'
+        result = self._assist(code)
+        for expected in ('all', 'any', 'abs'):
+            self.assert_completion_in_result(expected, 'builtin', result,
+                                             type='function')
+
+    def test_attribute_function_completion_proposal(self):
+        code = 'class Some(object):\n  def method(self):\n    self.'
+        result = self._assist(code)
+        self.assert_completion_in_result('method', 'attribute', result,
+                                         type='function')
+
+    def test_local_module_completion_proposal(self):
+        code = 'def foo():\n  import types\n  t'
+        result = self._assist(code)
+        self.assert_completion_in_result('types', 'imported', result,
+                                         type='module')
+
+    def test_global_module_completion_proposal(self):
+        code = 'import operator\no'
+        result = self._assist(code)
+        self.assert_completion_in_result('operator', 'imported', result,
+                                         type='module')
+
+    def test_attribute_module_completion_proposal(self):
+        code = 'class Some(object):\n  import os\nSome.o'
+        result = self._assist(code)
+        self.assert_completion_in_result('os', 'imported', result,
+                                         type='module')
+
+    def test_builtin_exception_completion_proposal(self):
+        code = 'def blah():\n  Z'
+        result = self._assist(code)
+        self.assert_completion_in_result('ZeroDivisionError', 'builtin',
+                                         result, type='class')
+
+    def test_keyword_completion_proposal(self):
+        code = 'f'
+        result = self._assist(code)
+        self.assert_completion_in_result('for', 'keyword', result, type=None)
+        self.assert_completion_in_result('from', 'keyword', result, type=None)
+
+    def test_parameter_keyword_completion_proposal(self):
+        code = 'def func(abc, aloha, alpha, amigo): pass\nfunc(a'
+        result = self._assist(code)
+        for expected in ('abc=', 'aloha=', 'alpha=', 'amigo='):
+            self.assert_completion_in_result(expected, 'parameter_keyword',
+                                             result, type=None)
+
+
+class CodeAssistInProjectsTest(unittest.TestCase):
+
+    def setUp(self):
+        super(CodeAssistInProjectsTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+        samplemod = testutils.create_module(self.project, 'samplemod')
+        code = 'class SampleClass(object):\n' \
+               '    def sample_method():\n        pass\n\n' \
+               'def sample_func():\n    pass\n' \
+               'sample_var = 10\n\n' \
+               'def _underlined_func():\n    pass\n\n'
+        samplemod.write(code)
+        package = testutils.create_package(self.project, 'package')
+        nestedmod = testutils.create_module(self.project, 'nestedmod', package)
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(self.__class__, self).tearDown()
+
+    def _assist(self, code, resource=None, **kwds):
+        return code_assist(self.project, code, len(code), resource, **kwds)
+
+    def assert_completion_in_result(self, name, scope, result):
+        for proposal in result:
+            if proposal.name == name and proposal.scope == scope:
+                return
+        self.fail('completion <%s> not proposed' % name)
+
+    def assert_completion_not_in_result(self, name, scope, result):
+        for proposal in result:
+            if proposal.name == name and proposal.scope == scope:
+                self.fail('completion <%s> was proposed' % name)
+
+    def test_simple_import(self):
+        code = 'import samplemod\nsample'
+        result = self._assist(code)
+        self.assert_completion_in_result('samplemod', 'imported', result)
+
+    def test_from_import_class(self):
+        code = 'from samplemod import SampleClass\nSample'
+        result = self._assist(code)
+        self.assert_completion_in_result('SampleClass', 'imported', result)
+
+    def test_from_import_function(self):
+        code = 'from samplemod import sample_func\nsample'
+        result = self._assist(code)
+        self.assert_completion_in_result('sample_func', 'imported', result)
+
+    def test_from_import_variable(self):
+        code = 'from samplemod import sample_var\nsample'
+        result = self._assist(code)
+        self.assert_completion_in_result('sample_var', 'imported', result)
+
+    def test_from_imports_inside_functions(self):
+        code = 'def f():\n    from samplemod import SampleClass\n    Sample'
+        result = self._assist(code)
+        self.assert_completion_in_result('SampleClass', 'imported', result)
+
+    def test_from_import_only_imports_imported(self):
+        code = 'from samplemod import sample_func\nSample'
+        result = self._assist(code)
+        self.assert_completion_not_in_result('SampleClass', 'global', result)
+
+    def test_from_import_star(self):
+        code = 'from samplemod import *\nSample'
+        result = self._assist(code)
+        self.assert_completion_in_result('SampleClass', 'imported', result)
+
+    def test_from_import_star2(self):
+        code = 'from samplemod import *\nsample'
+        result = self._assist(code)
+        self.assert_completion_in_result('sample_func', 'imported', result)
+        self.assert_completion_in_result('sample_var', 'imported', result)
+
+    def test_from_import_star_not_imporing_underlined(self):
+        code = 'from samplemod import *\n_under'
+        result = self._assist(code)
+        self.assert_completion_not_in_result('_underlined_func', 'global', result)
+
+    def test_from_package_import_mod(self):
+        code = 'from package import nestedmod\nnest'
+        result = self._assist(code)
+        self.assert_completion_in_result('nestedmod', 'imported', result)
+
+    def test_completing_after_dot(self):
+        code = 'class SampleClass(object):\n' \
+               '    def sample_method(self):\n' \
+               '        pass\n' \
+               'SampleClass.sam'
+        result = self._assist(code)
+        self.assert_completion_in_result('sample_method', 'attribute', result)
+
+    def test_completing_after_multiple_dots(self):
+        code = 'class Class1(object):\n' \
+               '    class Class2(object):\n' \
+               '        def sample_method(self):\n' \
+               '            pass\n' \
+               'Class1.Class2.sam'
+        result = self._assist(code)
+        self.assert_completion_in_result('sample_method', 'attribute', result)
+
+    def test_completing_after_self_dot(self):
+        code = 'class Sample(object):\n' \
+               '    def method1(self):\n' \
+               '        pass\n' \
+               '    def method2(self):\n' \
+               '        self.m'
+        result = self._assist(code)
+        self.assert_completion_in_result('method1', 'attribute', result)
+
+    def test_result_start_offset_for_dotted_completions(self):
+        code = 'class Sample(object):\n' \
+               '    def method1(self):\n' \
+               '        pass\n' \
+               'Sample.me'
+        self.assertEquals(len(code) - 2, starting_offset(code, len(code)))
+
+    def test_backslash_after_dots(self):
+        code = 'class Sample(object):\n' \
+               '    def a_method(self):\n' \
+               '        pass\n' \
+               'Sample.\\\n       a_m'
+        result = self._assist(code)
+        self.assert_completion_in_result('a_method', 'attribute', result)
+
+    def test_not_proposing_global_names_after_dot(self):
+        code = 'class Sample(object):\n' \
+               '    def a_method(self):\n' \
+               '        pass\n' \
+               'Sample.'
+        result = self._assist(code)
+        self.assert_completion_not_in_result('Sample', 'global', result)
+
+    def test_assist_on_relative_imports(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1 = testutils.create_module(self.project, 'mod1', pkg)
+        mod2 = testutils.create_module(self.project, 'mod2', pkg)
+        mod1.write('def a_func():\n    pass\n')
+        code = 'import mod1\nmod1.'
+        result = self._assist(code, resource=mod2)
+        self.assert_completion_in_result('a_func', 'imported', result)
+
+    def test_get_location_on_relative_imports(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1 = testutils.create_module(self.project, 'mod1', pkg)
+        mod2 = testutils.create_module(self.project, 'mod2', pkg)
+        mod1.write('def a_func():\n    pass\n')
+        code = 'import mod1\nmod1.a_func\n'
+        result = get_definition_location(self.project, code,
+                                         len(code) - 2, mod2)
+        self.assertEquals((mod1, 1), result)
+
+    def test_get_definition_location_for_builtins(self):
+        code = 'import sys\n'
+        result = get_definition_location(self.project, code,
+                                         len(code) - 2)
+        self.assertEquals((None, None), result)
+
+    def test_get_doc_on_relative_imports(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1 = testutils.create_module(self.project, 'mod1', pkg)
+        mod2 = testutils.create_module(self.project, 'mod2', pkg)
+        mod1.write('def a_func():\n    """hey"""\n    pass\n')
+        code = 'import mod1\nmod1.a_func\n'
+        result = get_doc(self.project, code, len(code) - 2, mod2)
+        self.assertTrue(result.endswith('hey'))
+
+    def test_get_doc_on_from_import_module(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('"""mod1 docs"""\nvar = 1\n')
+        code = 'from mod1 import var\n'
+        result = get_doc(self.project, code, code.index('mod1'))
+        result.index('mod1 docs')
+
+    def test_fixing_errors_with_maxfixes_in_resources(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'def f():\n    sldj sldj\ndef g():\n    ran'
+        mod.write(code)
+        result = self._assist(code, maxfixes=2, resource=mod)
+        self.assertTrue(len(result) > 0)
+
+    def test_completing_names_after_from_import(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('myvar = None\n')
+        result = self._assist('from mod1 import myva', resource=mod2)
+        self.assertTrue(len(result) > 0)
+        self.assert_completion_in_result('myvar', 'global', result)
+
+    def test_completing_names_after_from_import_and_sorted_proposals(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('myvar = None\n')
+        result = self._assist('from mod1 import myva', resource=mod2)
+        result = sorted_proposals(result)
+        self.assertTrue(len(result) > 0)
+        self.assert_completion_in_result('myvar', 'global', result)
+
+    def test_completing_names_after_from_import2(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('myvar = None\n')
+        result = self._assist('from mod1 import ', resource=mod2)
+        self.assertTrue(len(result) > 0)
+        self.assert_completion_in_result('myvar', 'global', result)
+
+    def test_starting_expression(self):
+        code = 'l = list()\nl.app'
+        self.assertEquals('l.app', starting_expression(code, len(code)))
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(CodeAssistTest))
+    result.addTests(unittest.makeSuite(CodeAssistInProjectsTest))
+    return result
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/contrib/finderrorstest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,52 @@
+import unittest
+
+from rope.contrib import finderrors
+from ropetest import testutils
+
+
+class FindErrorsTest(unittest.TestCase):
+
+    def setUp(self):
+        super(FindErrorsTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.mod = self.project.root.create_file('mod.py')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(FindErrorsTest, self).tearDown()
+
+    def test_unresolved_variables(self):
+        self.mod.write('print(var)\n')
+        result = finderrors.find_errors(self.project, self.mod)
+        self.assertEquals(1, len(result))
+        self.assertEquals(1, result[0].lineno)
+
+    def test_defined_later(self):
+        self.mod.write('print(var)\nvar = 1\n')
+        result = finderrors.find_errors(self.project, self.mod)
+        self.assertEquals(1, len(result))
+        self.assertEquals(1, result[0].lineno)
+
+    def test_ignoring_builtins(self):
+        self.mod.write('range(2)\n')
+        result = finderrors.find_errors(self.project, self.mod)
+        self.assertEquals(0, len(result))
+
+    def test_ignoring_none(self):
+        self.mod.write('var = None\n')
+        result = finderrors.find_errors(self.project, self.mod)
+        self.assertEquals(0, len(result))
+
+    def test_bad_attributes(self):
+        code = 'class C(object):\n' \
+               '    pass\n' \
+               'c = C()\n' \
+               'print(c.var)\n'
+        self.mod.write(code)
+        result = finderrors.find_errors(self.project, self.mod)
+        self.assertEquals(1, len(result))
+        self.assertEquals(4, result[0].lineno)
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/contrib/findittest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,120 @@
+from rope.base import exceptions
+import unittest
+
+from rope.contrib.findit import (find_occurrences, find_implementations,
+                                 find_definition)
+from ropetest import testutils
+
+
+class FindItTest(unittest.TestCase):
+
+    def setUp(self):
+        super(FindItTest, self).setUp()
+        self.project = testutils.sample_project()
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(FindItTest, self).tearDown()
+
+    def test_finding_occurrences(self):
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('a_var = 1\n')
+        result = find_occurrences(self.project, mod, 1)
+        self.assertEquals(mod, result[0].resource)
+        self.assertEquals(0, result[0].offset)
+        self.assertEquals(False, result[0].unsure)
+
+    def test_finding_occurrences_in_more_than_one_module(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('a_var = 1\n')
+        mod2.write('import mod1\nmy_var = mod1.a_var')
+        result = find_occurrences(self.project, mod1, 1)
+        self.assertEquals(2, len(result))
+        modules = (result[0].resource, result[1].resource)
+        self.assertTrue(mod1 in modules and mod2 in modules)
+
+    def test_finding_occurrences_matching_when_unsure(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('class C(object):\n    def a_func(self):\n        pass\n'
+                   'def f(arg):\n    arg.a_func()\n')
+        result = find_occurrences(
+            self.project, mod1, mod1.read().index('a_func'), unsure=True)
+        self.assertEquals(2, len(result))
+
+    def test_find_occurrences_resources_parameter(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('a_var = 1\n')
+        mod2.write('import mod1\nmy_var = mod1.a_var')
+        result = find_occurrences(self.project, mod1, 1, resources=[mod1])
+        self.assertEquals(1, len(result))
+        self.assertEquals((mod1, 0), (result[0].resource, result[0].offset))
+
+    def test_find_occurrences_and_class_hierarchies(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('class A(object):\n    def f():\n        pass\n'
+                   'class B(A):\n    def f():\n        pass\n')
+        offset = mod1.read().rindex('f')
+        result1 = find_occurrences(self.project, mod1, offset)
+        result2 = find_occurrences(self.project, mod1,
+                                   offset, in_hierarchy=True)
+        self.assertEquals(1, len(result1))
+        self.assertEquals(2, len(result2))
+
+    def test_trivial_find_implementations(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('class A(object):\n    def f(self):\n        pass\n')
+        offset = mod1.read().rindex('f(')
+        result = find_implementations(self.project, mod1, offset)
+        self.assertEquals([], result)
+
+    def test_find_implementations_and_not_returning_parents(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('class A(object):\n    def f(self):\n        pass\n'
+                   'class B(A):\n    def f(self):\n        pass\n')
+        offset = mod1.read().rindex('f(')
+        result = find_implementations(self.project, mod1, offset)
+        self.assertEquals([], result)
+
+    def test_find_implementations_real_implementation(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('class A(object):\n    def f(self):\n        pass\n'
+                   'class B(A):\n    def f(self):\n        pass\n')
+        offset = mod1.read().index('f(')
+        result = find_implementations(self.project, mod1, offset)
+        self.assertEquals(1, len(result))
+        self.assertEquals(mod1.read().rindex('f('), result[0].offset)
+
+    @testutils.assert_raises(exceptions.BadIdentifierError)
+    def test_find_implementations_real_implementation(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('class A(object):\n    pass\n')
+        offset = mod1.read().index('A')
+        result = find_implementations(self.project, mod1, offset)
+
+    def test_trivial_find_definition(self):
+        code = 'def a_func():\n    pass\na_func()'
+        result = find_definition(self.project, code, code.rindex('a_func'))
+        start = code.index('a_func')
+        self.assertEquals(start, result.offset)
+        self.assertEquals(None, result.resource)
+        self.assertEquals(1, result.lineno)
+        self.assertEquals((start, start + len('a_func')), result.region)
+
+    def test_find_definition_in_other_modules(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('var = 1\n')
+        code = 'import mod1\nprint(mod1.var)\n'
+        result = find_definition(self.project, code, code.index('var'))
+        self.assertEquals(mod1, result.resource)
+        self.assertEquals(0, result.offset)
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(FindItTest))
+    return result
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/contrib/fixmodnamestest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,56 @@
+import unittest
+
+from ropetest import testutils
+from rope.contrib.fixmodnames import FixModuleNames
+from rope.contrib.generate import create_module, create_package
+
+
+# HACK: for making this test work on case-insensitive file-systems, it
+# uses a name.replace('x', '_') fixer.
+class FixModuleNamesTest(unittest.TestCase):
+
+    def setUp(self):
+        super(FixModuleNamesTest, self).setUp()
+        self.project = testutils.sample_project()
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(FixModuleNamesTest, self).tearDown()
+
+    def test_simple_module_renaming(self):
+        mod = create_module(self.project, 'xod')
+        self.project.do(FixModuleNames(self.project).get_changes(_fixer))
+        self.assertFalse(mod.exists())
+        self.assertTrue(self.project.get_resource('_od.py').exists())
+
+    def test_packages_module_renaming(self):
+        pkg = create_package(self.project, 'xkg')
+        self.project.do(FixModuleNames(self.project).get_changes(_fixer))
+        self.assertFalse(pkg.exists())
+        self.assertTrue(self.project.get_resource('_kg/__init__.py').exists())
+
+    def test_fixing_contents(self):
+        mod1 = create_module(self.project, 'xod1')
+        mod2 = create_module(self.project, 'xod2')
+        mod1.write('import xod2\n')
+        mod2.write('import xod1\n')
+        self.project.do(FixModuleNames(self.project).get_changes(_fixer))
+        newmod1 = self.project.get_resource('_od1.py')
+        newmod2 = self.project.get_resource('_od2.py')
+        self.assertEquals('import _od2\n', newmod1.read())
+        self.assertEquals('import _od1\n', newmod2.read())
+
+    def test_handling_nested_modules(self):
+        pkg = create_package(self.project, 'xkg')
+        mod = create_module(self.project, 'xkg.xod')
+        self.project.do(FixModuleNames(self.project).get_changes(_fixer))
+        self.assertFalse(pkg.exists())
+        self.assertTrue(self.project.get_resource('_kg/__init__.py').exists())
+        self.assertTrue(self.project.get_resource('_kg/_od.py').exists())
+
+
+def _fixer(name):
+    return name.replace('x', '_')
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/contrib/generatetest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,265 @@
+import unittest
+
+from rope.base import exceptions
+from rope.contrib import generate
+from ropetest import testutils
+
+
+class GenerateTest(unittest.TestCase):
+
+    def setUp(self):
+        super(GenerateTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+        self.mod = testutils.create_module(self.project, 'mod1')
+        self.mod2 = testutils.create_module(self.project, 'mod2')
+        self.pkg = testutils.create_package(self.project, 'pkg')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(GenerateTest, self).tearDown()
+
+    def _get_generate(self, offset):
+        return generate.GenerateVariable(self.project, self.mod, offset)
+
+    def _get_generate_class(self, offset):
+        return generate.GenerateClass(self.project, self.mod, offset)
+
+    def _get_generate_module(self, offset):
+        return generate.GenerateModule(self.project, self.mod, offset)
+
+    def _get_generate_package(self, offset):
+        return generate.GeneratePackage(self.project, self.mod, offset)
+
+    def _get_generate_function(self, offset):
+        return generate.GenerateFunction(self.project, self.mod, offset)
+
+    def test_getting_location(self):
+        code = 'a_var = name\n'
+        self.mod.write(code)
+        generator = self._get_generate(code.index('name'))
+        self.assertEquals((self.mod, 1), generator.get_location())
+
+    def test_generating_variable(self):
+        code = 'a_var = name\n'
+        self.mod.write(code)
+        changes = self._get_generate(code.index('name')).get_changes()
+        self.project.do(changes)
+        self.assertEquals('name = None\n\n\na_var = name\n', self.mod.read())
+
+    def test_generating_variable_inserting_before_statement(self):
+        code = 'c = 1\nc = b\n'
+        self.mod.write(code)
+        changes = self._get_generate(code.index('b')).get_changes()
+        self.project.do(changes)
+        self.assertEquals('c = 1\nb = None\n\n\nc = b\n', self.mod.read())
+
+    def test_generating_variable_in_local_scopes(self):
+        code = 'def f():\n    c = 1\n    c = b\n'
+        self.mod.write(code)
+        changes = self._get_generate(code.index('b')).get_changes()
+        self.project.do(changes)
+        self.assertEquals('def f():\n    c = 1\n    b = None\n    c = b\n',
+                          self.mod.read())
+
+    def test_generating_variable_in_other_modules(self):
+        code = 'import mod2\nc = mod2.b\n'
+        self.mod.write(code)
+        generator = self._get_generate(code.index('b'))
+        self.project.do(generator.get_changes())
+        self.assertEquals((self.mod2, 1), generator.get_location())
+        self.assertEquals('b = None\n', self.mod2.read())
+
+    def test_generating_variable_in_classes(self):
+        code = 'class C(object):\n    def f(self):\n        pass\n' \
+               'c = C()\na_var = c.attr'
+        self.mod.write(code)
+        changes = self._get_generate(code.index('attr')).get_changes()
+        self.project.do(changes)
+        self.assertEquals(
+            'class C(object):\n    def f(self):\n        pass\n\n    attr = None\n' \
+            'c = C()\na_var = c.attr', self.mod.read())
+
+    def test_generating_variable_in_classes_removing_pass(self):
+        code = 'class C(object):\n    pass\nc = C()\na_var = c.attr'
+        self.mod.write(code)
+        changes = self._get_generate(code.index('attr')).get_changes()
+        self.project.do(changes)
+        self.assertEquals('class C(object):\n\n    attr = None\n' \
+                          'c = C()\na_var = c.attr', self.mod.read())
+
+    def test_generating_variable_in_packages(self):
+        code = 'import pkg\na = pkg.a\n'
+        self.mod.write(code)
+        generator = self._get_generate(code.rindex('a'))
+        self.project.do(generator.get_changes())
+        init = self.pkg.get_child('__init__.py')
+        self.assertEquals((init, 1), generator.get_location())
+        self.assertEquals('a = None\n', init.read())
+
+    def test_generating_classes(self):
+        code = 'c = C()\n'
+        self.mod.write(code)
+        changes = self._get_generate_class(code.index('C')).get_changes()
+        self.project.do(changes)
+        self.assertEquals('class C(object):\n    pass\n\n\nc = C()\n',
+                          self.mod.read())
+
+    def test_generating_modules(self):
+        code = 'import pkg\npkg.mod\n'
+        self.mod.write(code)
+        generator = self._get_generate_module(code.rindex('mod'))
+        self.project.do(generator.get_changes())
+        mod = self.pkg.get_child('mod.py')
+        self.assertEquals((mod, 1), generator.get_location())
+        self.assertEquals('import pkg.mod\npkg.mod\n', self.mod.read())
+
+    def test_generating_packages(self):
+        code = 'import pkg\npkg.pkg2\n'
+        self.mod.write(code)
+        generator = self._get_generate_package(code.rindex('pkg2'))
+        self.project.do(generator.get_changes())
+        pkg2 = self.pkg.get_child('pkg2')
+        init = pkg2.get_child('__init__.py')
+        self.assertEquals((init, 1), generator.get_location())
+        self.assertEquals('import pkg.pkg2\npkg.pkg2\n', self.mod.read())
+
+    def test_generating_function(self):
+        code = 'a_func()\n'
+        self.mod.write(code)
+        changes = self._get_generate_function(code.index('a_func')).get_changes()
+        self.project.do(changes)
+        self.assertEquals('def a_func():\n    pass\n\n\na_func()\n',
+                          self.mod.read())
+
+    def test_generating_modules_with_empty_primary(self):
+        code = 'mod\n'
+        self.mod.write(code)
+        generator = self._get_generate_module(code.rindex('mod'))
+        self.project.do(generator.get_changes())
+        mod = self.project.root.get_child('mod.py')
+        self.assertEquals((mod, 1), generator.get_location())
+        self.assertEquals('import mod\nmod\n', self.mod.read())
+
+    @testutils.assert_raises(exceptions.RefactoringError)
+    def test_generating_variable_already_exists(self):
+        code = 'b = 1\nc = b\n'
+        self.mod.write(code)
+        changes = self._get_generate(code.index('b')).get_changes()
+
+    @testutils.assert_raises(exceptions.RefactoringError)
+    def test_generating_variable_primary_cannot_be_determined(self):
+        code = 'c = can_not_be_found.b\n'
+        self.mod.write(code)
+        changes = self._get_generate(code.rindex('b')).get_changes()
+
+    @testutils.assert_raises(exceptions.RefactoringError)
+    def test_generating_modules_when_already_exists(self):
+        code = 'mod2\n'
+        self.mod.write(code)
+        generator = self._get_generate_module(code.rindex('mod'))
+        self.project.do(generator.get_changes())
+
+    def test_generating_static_methods(self):
+        code = 'class C(object):\n    pass\nC.a_func()\n'
+        self.mod.write(code)
+        changes = self._get_generate_function(code.index('a_func')).get_changes()
+        self.project.do(changes)
+        self.assertEquals(
+            'class C(object):\n\n    @staticmethod\n    def a_func():\n        pass\nC.a_func()\n',
+            self.mod.read())
+
+    def test_generating_methods(self):
+        code = 'class C(object):\n    pass\nc = C()\nc.a_func()\n'
+        self.mod.write(code)
+        changes = self._get_generate_function(code.index('a_func')).get_changes()
+        self.project.do(changes)
+        self.assertEquals(
+            'class C(object):\n\n    def a_func(self):\n        pass\n'
+            'c = C()\nc.a_func()\n',
+            self.mod.read())
+
+    def test_generating_constructors(self):
+        code = 'class C(object):\n    pass\nc = C()\n'
+        self.mod.write(code)
+        changes = self._get_generate_function(code.rindex('C')).get_changes()
+        self.project.do(changes)
+        self.assertEquals(
+            'class C(object):\n\n    def __init__(self):\n        pass\n'
+            'c = C()\n',
+            self.mod.read())
+
+    def test_generating_calls(self):
+        code = 'class C(object):\n    pass\nc = C()\nc()\n'
+        self.mod.write(code)
+        changes = self._get_generate_function(code.rindex('c')).get_changes()
+        self.project.do(changes)
+        self.assertEquals(
+            'class C(object):\n\n    def __call__(self):\n        pass\n'
+            'c = C()\nc()\n',
+            self.mod.read())
+
+    def test_generating_calls_in_other_modules(self):
+        self.mod2.write('class C(object):\n    pass\n')
+        code = 'import mod2\nc = mod2.C()\nc()\n'
+        self.mod.write(code)
+        changes = self._get_generate_function(code.rindex('c')).get_changes()
+        self.project.do(changes)
+        self.assertEquals(
+            'class C(object):\n\n    def __call__(self):\n        pass\n',
+            self.mod2.read())
+
+    def test_generating_function_handling_arguments(self):
+        code = 'a_func(1)\n'
+        self.mod.write(code)
+        changes = self._get_generate_function(code.index('a_func')).get_changes()
+        self.project.do(changes)
+        self.assertEquals('def a_func(arg0):\n    pass\n\n\na_func(1)\n',
+                          self.mod.read())
+
+    def test_generating_function_handling_keyword_xarguments(self):
+        code = 'a_func(p=1)\n'
+        self.mod.write(code)
+        changes = self._get_generate_function(code.index('a_func')).get_changes()
+        self.project.do(changes)
+        self.assertEquals('def a_func(p):\n    pass\n\n\na_func(p=1)\n',
+                          self.mod.read())
+
+    def test_generating_function_handling_arguments_better_naming(self):
+        code = 'a_var = 1\na_func(a_var)\n'
+        self.mod.write(code)
+        changes = self._get_generate_function(code.index('a_func')).get_changes()
+        self.project.do(changes)
+        self.assertEquals('a_var = 1\ndef a_func(a_var):\n    pass\n\n\na_func(a_var)\n',
+                          self.mod.read())
+
+    def test_generating_variable_in_other_modules2(self):
+        self.mod2.write('\n\n\nprint(1)\n')
+        code = 'import mod2\nc = mod2.b\n'
+        self.mod.write(code)
+        generator = self._get_generate(code.index('b'))
+        self.project.do(generator.get_changes())
+        self.assertEquals((self.mod2, 5), generator.get_location())
+        self.assertEquals('\n\n\nprint(1)\n\n\nb = None\n', self.mod2.read())
+
+    def test_generating_function_in_a_suite(self):
+        code = 'if True:\n    a_func()\n'
+        self.mod.write(code)
+        changes = self._get_generate_function(code.index('a_func')).get_changes()
+        self.project.do(changes)
+        self.assertEquals('def a_func():\n    pass\n\n\nif True:\n    a_func()\n',
+                          self.mod.read())
+
+    def test_generating_function_in_a_suite_in_a_function(self):
+        code = 'def f():\n    a = 1\n    if 1:\n        g()\n'
+        self.mod.write(code)
+        changes = self._get_generate_function(code.index('g()')).get_changes()
+        self.project.do(changes)
+        self.assertEquals(
+            'def f():\n    a = 1\n    def g():\n        pass\n'
+            '    if 1:\n        g()\n',
+            self.mod.read())
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/historytest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,409 @@
+import unittest
+
+import rope.base.history
+from rope.base import exceptions
+from rope.base.change import *
+from ropetest import testutils
+
+
+class HistoryTest(unittest.TestCase):
+
+    def setUp(self):
+        super(HistoryTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.history = self.project.history
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(HistoryTest, self).tearDown()
+
+    def test_undoing_writes(self):
+        my_file = self.project.root.create_file('my_file.txt')
+        my_file.write('text1')
+        self.history.undo()
+        self.assertEquals('', my_file.read())
+
+    def test_moving_files(self):
+        my_file = self.project.root.create_file('my_file.txt')
+        my_file.move('new_file.txt')
+        self.history.undo()
+        self.assertEquals('', my_file.read())
+
+    def test_moving_files_to_folders(self):
+        my_file = self.project.root.create_file('my_file.txt')
+        my_folder = self.project.root.create_folder('my_folder')
+        my_file.move(my_folder.path)
+        self.history.undo()
+        self.assertEquals('', my_file.read())
+
+    def test_writing_files_that_does_not_change_contents(self):
+        my_file = self.project.root.create_file('my_file.txt')
+        my_file.write('')
+        self.project.history.undo()
+        self.assertFalse(my_file.exists())
+
+class IsolatedHistoryTest(unittest.TestCase):
+
+    def setUp(self):
+        super(IsolatedHistoryTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.history = rope.base.history.History(self.project)
+        self.file1 = self.project.root.create_file('file1.txt')
+        self.file2 = self.project.root.create_file('file2.txt')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(IsolatedHistoryTest, self).tearDown()
+
+    def test_simple_undo(self):
+        change = ChangeContents(self.file1, '1')
+        self.history.do(change)
+        self.assertEquals('1', self.file1.read())
+        self.history.undo()
+        self.assertEquals('', self.file1.read())
+
+    def test_tobe_undone(self):
+        change1 = ChangeContents(self.file1, '1')
+        self.assertEquals(None, self.history.tobe_undone)
+        self.history.do(change1)
+        self.assertEquals(change1, self.history.tobe_undone)
+        change2 = ChangeContents(self.file1, '2')
+        self.history.do(change2)
+        self.assertEquals(change2, self.history.tobe_undone)
+        self.history.undo()
+        self.assertEquals(change1, self.history.tobe_undone)
+
+    def test_tobe_redone(self):
+        change = ChangeContents(self.file1, '1')
+        self.history.do(change)
+        self.assertEquals(None, self.history.tobe_redone)
+        self.history.undo()
+        self.assertEquals(change, self.history.tobe_redone)
+
+    @testutils.assert_raises(exceptions.HistoryError)
+    def test_undo_limit(self):
+        history = rope.base.history.History(self.project, maxundos=1)
+        history.do(ChangeContents(self.file1, '1'))
+        history.do(ChangeContents(self.file1, '2'))
+        try:
+            history.undo()
+            history.undo()
+        finally:
+            self.assertEquals('1', self.file1.read())
+
+    def test_simple_redo(self):
+        change = ChangeContents(self.file1, '1')
+        self.history.do(change)
+        self.history.undo()
+        self.history.redo()
+        self.assertEquals('1', self.file1.read())
+
+    def test_simple_re_undo(self):
+        change = ChangeContents(self.file1, '1')
+        self.history.do(change)
+        self.history.undo()
+        self.history.redo()
+        self.history.undo()
+        self.assertEquals('', self.file1.read())
+
+    def test_multiple_undos(self):
+        change = ChangeContents(self.file1, '1')
+        self.history.do(change)
+        change = ChangeContents(self.file1, '2')
+        self.history.do(change)
+        self.history.undo()
+        self.assertEquals('1', self.file1.read())
+        change = ChangeContents(self.file1, '3')
+        self.history.do(change)
+        self.history.undo()
+        self.assertEquals('1', self.file1.read())
+        self.history.redo()
+        self.assertEquals('3', self.file1.read())
+
+    @testutils.assert_raises(exceptions.HistoryError)
+    def test_undo_list_underflow(self):
+        self.history.undo()
+
+    @testutils.assert_raises(exceptions.HistoryError)
+    def test_redo_list_underflow(self):
+        self.history.redo()
+
+    @testutils.assert_raises(exceptions.HistoryError)
+    def test_dropping_undone_changes(self):
+        self.file1.write('1')
+        self.history.undo(drop=True)
+        self.history.redo()
+
+    def test_undoing_choosen_changes(self):
+        change = ChangeContents(self.file1, '1')
+        self.history.do(change)
+        self.history.undo(change)
+        self.assertEquals('', self.file1.read())
+        self.assertFalse(self.history.undo_list)
+
+    def test_undoing_choosen_changes2(self):
+        change1 = ChangeContents(self.file1, '1')
+        self.history.do(change1)
+        self.history.do(ChangeContents(self.file1, '2'))
+        self.history.undo(change1)
+        self.assertEquals('', self.file1.read())
+        self.assertFalse(self.history.undo_list)
+
+    def test_undoing_choosen_changes_not_undoing_others(self):
+        change1 = ChangeContents(self.file1, '1')
+        self.history.do(change1)
+        self.history.do(ChangeContents(self.file2, '2'))
+        self.history.undo(change1)
+        self.assertEquals('', self.file1.read())
+        self.assertEquals('2', self.file2.read())
+
+    def test_undoing_writing_after_moving(self):
+        change1 = ChangeContents(self.file1, '1')
+        self.history.do(change1)
+        self.history.do(MoveResource(self.file1, 'file3.txt'))
+        file3 = self.project.get_resource('file3.txt')
+        self.history.undo(change1)
+        self.assertEquals('', self.file1.read())
+        self.assertFalse(file3.exists())
+
+    def test_undoing_folder_movements_for_undoing_writes_inside_it(self):
+        folder = self.project.root.create_folder('folder')
+        file3 = folder.create_file('file3.txt')
+        change1 = ChangeContents(file3, '1')
+        self.history.do(change1)
+        self.history.do(MoveResource(folder, 'new_folder'))
+        new_folder = self.project.get_resource('new_folder')
+        self.history.undo(change1)
+        self.assertEquals('', file3.read())
+        self.assertFalse(new_folder.exists())
+
+    def test_undoing_changes_that_depend_on_a_dependant_change(self):
+        change1 = ChangeContents(self.file1, '1')
+        self.history.do(change1)
+        changes = ChangeSet('2nd change')
+        changes.add_change(ChangeContents(self.file1, '2'))
+        changes.add_change(ChangeContents(self.file2, '2'))
+        self.history.do(changes)
+        self.history.do(MoveResource(self.file2, 'file3.txt'))
+        file3 = self.project.get_resource('file3.txt')
+
+        self.history.undo(change1)
+        self.assertEquals('', self.file1.read())
+        self.assertEquals('', self.file2.read())
+        self.assertFalse(file3.exists())
+
+    def test_undoing_writes_for_undoing_folder_movements_containing_it(self):
+        folder = self.project.root.create_folder('folder')
+        old_file = folder.create_file('file3.txt')
+        change1 = MoveResource(folder, 'new_folder')
+        self.history.do(change1)
+        new_file = self.project.get_resource('new_folder/file3.txt')
+        self.history.do(ChangeContents(new_file, '1'))
+        self.history.undo(change1)
+        self.assertEquals('', old_file.read())
+        self.assertFalse(new_file.exists())
+
+    @testutils.assert_raises(exceptions.HistoryError)
+    def test_undoing_not_available_change(self):
+        change = ChangeContents(self.file1, '1')
+        self.history.undo(change)
+
+    def test_ignoring_ignored_resources(self):
+        self.project.set('ignored_resources', ['ignored*'])
+        ignored = self.project.get_file('ignored.txt')
+        change = CreateResource(ignored)
+        self.history.do(change)
+        self.assertTrue(ignored.exists())
+        self.assertEquals(0, len(self.history.undo_list))
+
+    def test_get_file_undo_list_simple(self):
+        change = ChangeContents(self.file1, '1')
+        self.history.do(change)
+        self.assertEquals(set([change]),
+                          set(self.history.get_file_undo_list(self.file1)))
+
+    def test_get_file_undo_list_for_moves(self):
+        change = MoveResource(self.file1, 'file2.txt')
+        self.history.do(change)
+        self.assertEquals(set([change]),
+                          set(self.history.get_file_undo_list(self.file1)))
+
+    # XXX: What happens for moves before the file is created?
+    def xxx_test_get_file_undo_list_and_moving_its_contining_folder(self):
+        folder = self.project.root.create_folder('folder')
+        old_file = folder.create_file('file3.txt')
+        change1 = MoveResource(folder, 'new_folder')
+        self.history.do(change1)
+        self.assertEquals(set([change1]),
+                          set(self.history.get_file_undo_list(old_file)))
+
+    def test_clearing_redo_list_after_do(self):
+        change = ChangeContents(self.file1, '1')
+        self.history.do(change)
+        self.history.undo()
+        self.history.do(change)
+        self.assertEquals(0, len(self.history.redo_list))
+
+    @testutils.assert_raises(exceptions.HistoryError)
+    def test_undoing_a_not_yet_performed_change(self):
+        change = ChangeContents(self.file1, '1')
+        str(change)
+        change.undo()
+
+    def test_clearing_up_the_history(self):
+        change1 = ChangeContents(self.file1, '1')
+        change2 = ChangeContents(self.file1, '2')
+        self.history.do(change1)
+        self.history.do(change2)
+        self.history.undo()
+        self.history.clear()
+        self.assertEquals(0, len(self.history.undo_list))
+        self.assertEquals(0, len(self.history.redo_list))
+
+    def test_redoing_choosen_changes_not_undoing_others(self):
+        change1 = ChangeContents(self.file1, '1')
+        change2 = ChangeContents(self.file2, '2')
+        self.history.do(change1)
+        self.history.do(change2)
+        self.history.undo()
+        self.history.undo()
+        redone = self.history.redo(change2)
+        self.assertEquals([change2], redone)
+        self.assertEquals('', self.file1.read())
+        self.assertEquals('2', self.file2.read())
+
+
+class SavingHistoryTest(unittest.TestCase):
+
+    def setUp(self):
+        super(SavingHistoryTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.history = rope.base.history.History(self.project)
+        self.to_data = ChangeToData()
+        self.to_change = DataToChange(self.project)
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(SavingHistoryTest, self).tearDown()
+
+    def test_simple_set_saving(self):
+        data = self.to_data(ChangeSet('testing'))
+        change = self.to_change(data)
+        self.assertEquals('testing', str(change))
+
+    def test_simple_change_content_saving(self):
+        myfile = self.project.get_file('myfile.txt')
+        myfile.create()
+        myfile.write('1')
+        data = self.to_data(ChangeContents(myfile, '2'))
+        change = self.to_change(data)
+        self.history.do(change)
+        self.assertEquals('2', myfile.read())
+        self.history.undo()
+        self.assertEquals('1', change.old_contents)
+
+    def test_move_resource_saving(self):
+        myfile = self.project.root.create_file('myfile.txt')
+        myfolder = self.project.root.create_folder('myfolder')
+        data = self.to_data(MoveResource(myfile, 'myfolder'))
+        change = self.to_change(data)
+        self.history.do(change)
+        self.assertFalse(myfile.exists())
+        self.assertTrue(myfolder.has_child('myfile.txt'))
+        self.history.undo()
+        self.assertTrue(myfile.exists())
+        self.assertFalse(myfolder.has_child('myfile.txt'))
+
+    def test_move_resource_saving_for_folders(self):
+        myfolder = self.project.root.create_folder('myfolder')
+        newfolder = self.project.get_folder('newfolder')
+        change = MoveResource(myfolder, 'newfolder')
+        self.history.do(change)
+
+        data = self.to_data(change)
+        change = self.to_change(data)
+        change.undo()
+        self.assertTrue(myfolder.exists())
+        self.assertFalse(newfolder.exists())
+
+    def test_create_file_saving(self):
+        myfile = self.project.get_file('myfile.txt')
+        data = self.to_data(CreateFile(self.project.root, 'myfile.txt'))
+        change = self.to_change(data)
+        self.history.do(change)
+        self.assertTrue(myfile.exists())
+        self.history.undo()
+        self.assertFalse(myfile.exists())
+
+    def test_create_folder_saving(self):
+        myfolder = self.project.get_folder('myfolder')
+        data = self.to_data(CreateFolder(self.project.root, 'myfolder'))
+        change = self.to_change(data)
+        self.history.do(change)
+        self.assertTrue(myfolder.exists())
+        self.history.undo()
+        self.assertFalse(myfolder.exists())
+
+    def test_create_resource_saving(self):
+        myfile = self.project.get_file('myfile.txt')
+        data = self.to_data(CreateResource(myfile))
+        change = self.to_change(data)
+        self.history.do(change)
+        self.assertTrue(myfile.exists())
+        self.history.undo()
+        self.assertFalse(myfile.exists())
+
+    def test_remove_resource_saving(self):
+        myfile = self.project.root.create_file('myfile.txt')
+        data = self.to_data(RemoveResource(myfile))
+        change = self.to_change(data)
+        self.history.do(change)
+        self.assertFalse(myfile.exists())
+
+    def test_change_set_saving(self):
+        change = ChangeSet('testing')
+        myfile = self.project.get_file('myfile.txt')
+        change.add_change(CreateResource(myfile))
+        change.add_change(ChangeContents(myfile, '1'))
+
+        data = self.to_data(change)
+        change = self.to_change(data)
+        self.history.do(change)
+        self.assertEquals('1', myfile.read())
+        self.history.undo()
+        self.assertFalse(myfile.exists())
+
+    def test_writing_and_reading_history(self):
+        history_file = self.project.get_file('history.pickle')
+        self.project.set('save_history', True)
+        history = rope.base.history.History(self.project)
+        myfile = self.project.get_file('myfile.txt')
+        history.do(CreateResource(myfile))
+        history.write()
+
+        history = rope.base.history.History(self.project)
+        history.undo()
+        self.assertFalse(myfile.exists())
+
+    def test_writing_and_reading_history2(self):
+        history_file = self.project.get_file('history.pickle')
+        self.project.set('save_history', True)
+        history = rope.base.history.History(self.project)
+        myfile = self.project.get_file('myfile.txt')
+        history.do(CreateResource(myfile))
+        history.undo()
+        history.write()
+
+        history = rope.base.history.History(self.project)
+        history.redo()
+        self.assertTrue(myfile.exists())
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(HistoryTest))
+    result.addTests(unittest.makeSuite(IsolatedHistoryTest))
+    result.addTests(unittest.makeSuite(SavingHistoryTest))
+    return result
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/objectdbtest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,160 @@
+import unittest
+
+from rope.base.oi import objectdb, memorydb
+from ropetest import testutils
+
+
+def _do_for_all_dbs(function):
+    def called(self):
+        for db in self.dbs:
+            function(self, db)
+    return called
+
+
+class _MockValidation(object):
+
+    def is_value_valid(self, value):
+        return value != -1
+
+    def is_more_valid(self, new, old):
+        return new != -1
+
+    def is_file_valid(self, path):
+        return path != 'invalid'
+
+    def is_scope_valid(self, path, key):
+        return path != 'invalid' and key != 'invalid'
+
+
+class _MockFileListObserver(object):
+
+    log = ''
+
+    def added(self, path):
+        self.log += 'added %s ' % path
+
+    def removed(self, path):
+        self.log += 'removed %s ' % path
+
+
+class ObjectDBTest(unittest.TestCase):
+
+    def setUp(self):
+        super(ObjectDBTest, self).setUp()
+        self.project = testutils.sample_project()
+        validation = _MockValidation()
+        self.dbs = [
+            objectdb.ObjectDB(memorydb.MemoryDB(self.project), validation)]
+
+    def tearDown(self):
+        for db in self.dbs:
+            db.write()
+        testutils.remove_project(self.project)
+        super(ObjectDBTest, self).tearDown()
+
+    @_do_for_all_dbs
+    def test_simple_per_name(self, db):
+        db.add_pername('file', 'key', 'name', 1)
+        self.assertEqual(1, db.get_pername('file', 'key', 'name'))
+
+    @_do_for_all_dbs
+    def test_simple_per_name_does_not_exist(self, db):
+        self.assertEquals(None, db.get_pername('file', 'key', 'name'))
+
+    @_do_for_all_dbs
+    def test_simple_per_name_after_syncing(self, db):
+        db.add_pername('file', 'key', 'name', 1)
+        db.write()
+        self.assertEquals(1, db.get_pername('file', 'key', 'name'))
+
+    @_do_for_all_dbs
+    def test_getting_returned(self, db):
+        db.add_callinfo('file', 'key', (1, 2), 3)
+        self.assertEquals(3, db.get_returned('file', 'key', (1, 2)))
+
+    @_do_for_all_dbs
+    def test_getting_returned_when_does_not_match(self, db):
+        db.add_callinfo('file', 'key', (1, 2), 3)
+        self.assertEquals(None, db.get_returned('file', 'key', (1, 1)))
+
+    @_do_for_all_dbs
+    def test_getting_call_info(self, db):
+        db.add_callinfo('file', 'key', (1, 2), 3)
+
+        call_infos = list(db.get_callinfos('file', 'key'))
+        self.assertEquals(1, len(call_infos))
+        self.assertEquals((1, 2), call_infos[0].get_parameters())
+        self.assertEquals(3, call_infos[0].get_returned())
+
+    @_do_for_all_dbs
+    def test_invalid_per_name(self, db):
+        db.add_pername('file', 'key', 'name', -1)
+        self.assertEquals(None, db.get_pername('file', 'key', 'name'))
+
+    @_do_for_all_dbs
+    def test_overwriting_per_name(self, db):
+        db.add_pername('file', 'key', 'name', 1)
+        db.add_pername('file', 'key', 'name', 2)
+        self.assertEquals(2, db.get_pername('file', 'key', 'name'))
+
+    @_do_for_all_dbs
+    def test_not_overwriting_with_invalid_per_name(self, db):
+        db.add_pername('file', 'key', 'name', 1)
+        db.add_pername('file', 'key', 'name', -1)
+        self.assertEquals(1, db.get_pername('file', 'key', 'name'))
+
+    @_do_for_all_dbs
+    def test_getting_invalid_returned(self, db):
+        db.add_callinfo('file', 'key', (1, 2), -1)
+        self.assertEquals(None, db.get_returned('file', 'key', (1, 2)))
+
+    @_do_for_all_dbs
+    def test_not_overwriting_with_invalid_returned(self, db):
+        db.add_callinfo('file', 'key', (1, 2), 3)
+        db.add_callinfo('file', 'key', (1, 2), -1)
+        self.assertEquals(3, db.get_returned('file', 'key', (1, 2)))
+
+    @_do_for_all_dbs
+    def test_get_files(self, db):
+        db.add_callinfo('file1', 'key', (1, 2), 3)
+        db.add_callinfo('file2', 'key', (1, 2), 3)
+        self.assertEquals(set(['file1', 'file2']), set(db.get_files()))
+
+    @_do_for_all_dbs
+    def test_validating_files(self, db):
+        db.add_callinfo('invalid', 'key', (1, 2), 3)
+        db.validate_files()
+        self.assertEquals(0, len(db.get_files()))
+
+    @_do_for_all_dbs
+    def test_validating_file_for_scopes(self, db):
+        db.add_callinfo('file', 'invalid', (1, 2), 3)
+        db.validate_file('file')
+        self.assertEquals(1, len(db.get_files()))
+        self.assertEquals(0, len(list(db.get_callinfos('file', 'invalid'))))
+
+    @_do_for_all_dbs
+    def test_validating_file_moved(self, db):
+        db.add_callinfo('file', 'key', (1, 2), 3)
+
+        db.file_moved('file', 'newfile')
+        self.assertEquals(1, len(db.get_files()))
+        self.assertEquals(1, len(list(db.get_callinfos('newfile', 'key'))))
+
+    @_do_for_all_dbs
+    def test_using_file_list_observer(self, db):
+        db.add_callinfo('invalid', 'key', (1, 2), 3)
+        observer = _MockFileListObserver()
+        db.add_file_list_observer(observer)
+        db.validate_files()
+        self.assertEquals('removed invalid ', observer.log)
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(ObjectDBTest))
+    return result
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/objectinfertest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,329 @@
+import unittest
+
+import rope.base.project
+import rope.base.builtins
+from ropetest import testutils
+
+
+class ObjectInferTest(unittest.TestCase):
+
+    def setUp(self):
+        super(ObjectInferTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(ObjectInferTest, self).tearDown()
+
+    def test_simple_type_inferencing(self):
+        code = 'class Sample(object):\n    pass\na_var = Sample()\n'
+        scope = self.pycore.get_string_scope(code)
+        sample_class = scope['Sample'].get_object()
+        a_var = scope['a_var'].get_object()
+        self.assertEquals(sample_class, a_var.get_type())
+
+    def test_simple_type_inferencing_classes_defined_in_holding_scope(self):
+        code = 'class Sample(object):\n    pass\n' \
+               'def a_func():\n    a_var = Sample()\n'
+        scope = self.pycore.get_string_scope(code)
+        sample_class = scope['Sample'].get_object()
+        a_var = scope['a_func'].get_object().\
+                        get_scope()['a_var'].get_object()
+        self.assertEquals(sample_class, a_var.get_type())
+
+    def test_simple_type_inferencing_classes_in_class_methods(self):
+        code = 'class Sample(object):\n    pass\n' \
+               'class Another(object):\n' \
+               '    def a_method():\n        a_var = Sample()\n'
+        scope = self.pycore.get_string_scope(code)
+        sample_class = scope['Sample'].get_object()
+        another_class = scope['Another'].get_object()
+        a_var = another_class['a_method'].\
+                        get_object().get_scope()['a_var'].get_object()
+        self.assertEquals(sample_class, a_var.get_type())
+
+    def test_simple_type_inferencing_class_attributes(self):
+        code = 'class Sample(object):\n    pass\n' \
+               'class Another(object):\n' \
+               '    def __init__(self):\n        self.a_var = Sample()\n'
+        scope = self.pycore.get_string_scope(code)
+        sample_class = scope['Sample'].get_object()
+        another_class = scope['Another'].get_object()
+        a_var = another_class['a_var'].get_object()
+        self.assertEquals(sample_class, a_var.get_type())
+
+    def test_simple_type_inferencing_for_in_class_assignments(self):
+        code = 'class Sample(object):\n    pass\n' \
+               'class Another(object):\n    an_attr = Sample()\n'
+        scope = self.pycore.get_string_scope(code)
+        sample_class = scope['Sample'].get_object()
+        another_class = scope['Another'].get_object()
+        an_attr = another_class['an_attr'].get_object()
+        self.assertEquals(sample_class, an_attr.get_type())
+
+    def test_simple_type_inferencing_for_chained_assignments(self):
+        mod = 'class Sample(object):\n    pass\n' \
+              'copied_sample = Sample'
+        mod_scope = self.project.pycore.get_string_scope(mod)
+        sample_class = mod_scope['Sample']
+        copied_sample = mod_scope['copied_sample']
+        self.assertEquals(sample_class.get_object(),
+                          copied_sample.get_object())
+
+    def test_following_chained_assignments_avoiding_circles(self):
+        mod = 'class Sample(object):\n    pass\n' \
+              'sample_class = Sample\n' \
+              'sample_class = sample_class\n'
+        mod_scope = self.project.pycore.get_string_scope(mod)
+        sample_class = mod_scope['Sample']
+        sample_class_var = mod_scope['sample_class']
+        self.assertEquals(sample_class.get_object(),
+                          sample_class_var.get_object())
+
+    def test_function_returned_object_static_type_inference1(self):
+        src = 'class Sample(object):\n    pass\n' \
+              'def a_func():\n    return Sample\n' \
+              'a_var = a_func()\n'
+        scope = self.project.pycore.get_string_scope(src)
+        sample_class = scope['Sample']
+        a_var = scope['a_var']
+        self.assertEquals(sample_class.get_object(), a_var.get_object())
+
+    def test_function_returned_object_static_type_inference2(self):
+        src = 'class Sample(object):\n    pass\n' \
+              'def a_func():\n    return Sample()\n' \
+              'a_var = a_func()\n'
+        scope = self.project.pycore.get_string_scope(src)
+        sample_class = scope['Sample'].get_object()
+        a_var = scope['a_var'].get_object()
+        self.assertEquals(sample_class, a_var.get_type())
+
+    def test_recursive_function_returned_object_static_type_inference(self):
+        src = 'class Sample(object):\n    pass\n' \
+              'def a_func():\n' \
+              '    if True:\n        return Sample()\n' \
+              '    else:\n        return a_func()\n' \
+              'a_var = a_func()\n'
+        scope = self.project.pycore.get_string_scope(src)
+        sample_class = scope['Sample'].get_object()
+        a_var = scope['a_var'].get_object()
+        self.assertEquals(sample_class, a_var.get_type())
+
+    def test_function_returned_object_using_call_special_function_static_type_inference(self):
+        src = 'class Sample(object):\n' \
+              '    def __call__(self):\n        return Sample\n' \
+              'sample = Sample()\na_var = sample()'
+        scope = self.project.pycore.get_string_scope(src)
+        sample_class = scope['Sample']
+        a_var = scope['a_var']
+        self.assertEquals(sample_class.get_object(), a_var.get_object())
+
+    def test_list_type_inferencing(self):
+        src = 'class Sample(object):\n    pass\na_var = [Sample()]\n'
+        scope = self.pycore.get_string_scope(src)
+        sample_class = scope['Sample'].get_object()
+        a_var = scope['a_var'].get_object()
+        self.assertNotEquals(sample_class, a_var.get_type())
+
+    def test_attributed_object_inference(self):
+        src = 'class Sample(object):\n' \
+              '    def __init__(self):\n        self.a_var = None\n' \
+              '    def set(self):\n        self.a_var = Sample()\n'
+        scope = self.pycore.get_string_scope(src)
+        sample_class = scope['Sample'].get_object()
+        a_var = sample_class['a_var'].get_object()
+        self.assertEquals(sample_class, a_var.get_type())
+
+    def test_getting_property_attributes(self):
+        src = 'class A(object):\n    pass\n' \
+              'def f(*args):\n    return A()\n' \
+              'class B(object):\n    p = property(f)\n' \
+              'a_var = B().p\n'
+        pymod = self.pycore.get_string_module(src)
+        a_class = pymod['A'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(a_class, a_var.get_type())
+
+    def test_getting_property_attributes_with_method_getters(self):
+        src = 'class A(object):\n    pass\n' \
+              'class B(object):\n    def p_get(self):\n        return A()\n' \
+              '    p = property(p_get)\n' \
+              'a_var = B().p\n'
+        pymod = self.pycore.get_string_module(src)
+        a_class = pymod['A'].get_object()
+        a_var = pymod['a_var'].get_object()
+        self.assertEquals(a_class, a_var.get_type())
+
+    def test_lambda_functions(self):
+        code = 'class C(object):\n    pass\n' \
+               'l = lambda: C()\na_var = l()'
+        mod = self.pycore.get_string_module(code)
+        c_class = mod['C'].get_object()
+        a_var = mod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_mixing_subscript_with_tuple_assigns(self):
+        code = 'class C(object):\n    attr = 0\n' \
+               'd = {}\nd[0], b = (0, C())\n'
+        mod = self.pycore.get_string_module(code)
+        c_class = mod['C'].get_object()
+        a_var = mod['b'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_mixing_ass_attr_with_tuple_assignment(self):
+        code = 'class C(object):\n    attr = 0\n' \
+               'c = C()\nc.attr, b = (0, C())\n'
+        mod = self.pycore.get_string_module(code)
+        c_class = mod['C'].get_object()
+        a_var = mod['b'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_mixing_slice_with_tuple_assigns(self):
+        mod = self.pycore.get_string_module(
+            'class C(object):\n    attr = 0\n'
+            'd = [None] * 3\nd[0:2], b = ((0,), C())\n')
+        c_class = mod['C'].get_object()
+        a_var = mod['b'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_nested_tuple_assignments(self):
+        mod = self.pycore.get_string_module(
+            'class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+            'a, (b, c) = (C1(), (C2(), C1()))\n')
+        c1_class = mod['C1'].get_object()
+        c2_class = mod['C2'].get_object()
+        a_var = mod['a'].get_object()
+        b_var = mod['b'].get_object()
+        c_var = mod['c'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+        self.assertEquals(c1_class, c_var.get_type())
+
+    def test_empty_tuples(self):
+        mod = self.pycore.get_string_module('t = ()\na, b = t\n')
+        a = mod['a'].get_object()
+
+    def test_handling_generator_functions(self):
+        code = 'class C(object):\n    pass\n' \
+               'def f():\n    yield C()\n' \
+               'for c in f():\n    a_var = c\n'
+        mod = self.pycore.get_string_module(code)
+        c_class = mod['C'].get_object()
+        a_var = mod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_handling_generator_functions_for_strs(self):
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('def f():\n    yield ""\n'
+                  'for s in f():\n    a_var = s\n')
+        pymod = self.pycore.resource_to_pyobject(mod)
+        a_var = pymod['a_var'].get_object()
+        self.assertTrue(isinstance(a_var.get_type(), rope.base.builtins.Str))
+
+    def test_considering_nones_to_be_unknowns(self):
+        code = 'class C(object):\n    pass\n' \
+               'a_var = None\na_var = C()\na_var = None\n'
+        mod = self.pycore.get_string_module(code)
+        c_class = mod['C'].get_object()
+        a_var = mod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_basic_list_comprehensions(self):
+        code = 'class C(object):\n    pass\n' \
+               'l = [C() for i in range(1)]\na_var = l[0]\n'
+        mod = self.pycore.get_string_module(code)
+        c_class = mod['C'].get_object()
+        a_var = mod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_basic_generator_expressions(self):
+        code = 'class C(object):\n    pass\n' \
+               'l = (C() for i in range(1))\na_var = list(l)[0]\n'
+        mod = self.pycore.get_string_module(code)
+        c_class = mod['C'].get_object()
+        a_var = mod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_list_comprehensions_and_loop_var(self):
+        code = 'class C(object):\n    pass\n' \
+               'c_objects = [C(), C()]\n' \
+               'l = [c for c in c_objects]\na_var = l[0]\n'
+        mod = self.pycore.get_string_module(code)
+        c_class = mod['C'].get_object()
+        a_var = mod['a_var'].get_object()
+        self.assertEquals(c_class, a_var.get_type())
+
+    def test_list_comprehensions_and_multiple_loop_var(self):
+        code = 'class C1(object):\n    pass\n' \
+               'class C2(object):\n    pass\n' \
+               'l = [(c1, c2) for c1 in [C1()] for c2 in [C2()]]\n' \
+               'a, b = l[0]\n'
+        mod = self.pycore.get_string_module(code)
+        c1_class = mod['C1'].get_object()
+        c2_class = mod['C2'].get_object()
+        a_var = mod['a'].get_object()
+        b_var = mod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_list_comprehensions_and_multiple_iters(self):
+        mod = self.pycore.get_string_module(
+            'class C1(object):\n    pass\nclass C2(object):\n    pass\n'
+            'l = [(c1, c2) for c1, c2 in [(C1(), C2())]]\n'
+            'a, b = l[0]\n')
+        c1_class = mod['C1'].get_object()
+        c2_class = mod['C2'].get_object()
+        a_var = mod['a'].get_object()
+        b_var = mod['b'].get_object()
+        self.assertEquals(c1_class, a_var.get_type())
+        self.assertEquals(c2_class, b_var.get_type())
+
+    def test_we_know_the_type_of_catched_exceptions(self):
+        code = 'class MyError(Exception):\n    pass\n' \
+               'try:\n    raise MyError()\n' \
+               'except MyError, e:\n    pass\n'
+        mod = self.pycore.get_string_module(
+            code)
+        my_error = mod['MyError'].get_object()
+        e_var = mod['e'].get_object()
+        self.assertEquals(my_error, e_var.get_type())
+
+    def test_we_know_the_type_of_catched_multiple_excepts(self):
+        code = 'class MyError(Exception):\n    pass\n' \
+               'try:\n    raise MyError()\n' \
+               'except (MyError, Exception), e:\n    pass\n'
+        mod = self.pycore.get_string_module(
+            code)
+        my_error = mod['MyError'].get_object()
+        e_var = mod['e'].get_object()
+        self.assertEquals(my_error, e_var.get_type())
+
+    def test_using_property_as_decorators(self):
+        code = 'class A(object):\n    pass\n' \
+               'class B(object):\n' \
+               '    @property\n    def f(self):\n        return A()\n' \
+               'b = B()\nvar = b.f\n'
+        mod = self.pycore.get_string_module(code)
+        var = mod['var'].get_object()
+        a = mod['A'].get_object()
+        self.assertEquals(a, var.get_type())
+
+    def test_using_property_as_decorators_and_passing_parameter(self):
+        code = 'class B(object):\n' \
+               '    @property\n    def f(self):\n        return self\n' \
+               'b = B()\nvar = b.f\n'
+        mod = self.pycore.get_string_module(code)
+        var = mod['var'].get_object()
+        a = mod['B'].get_object()
+        self.assertEquals(a, var.get_type())
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(ObjectInferTest))
+    return result
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/projecttest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,958 @@
+import os.path
+import unittest
+
+from rope.base.exceptions import RopeError, ResourceNotFoundError
+from rope.base.fscommands import FileSystemCommands
+from rope.base.libutils import path_to_resource
+from rope.base.project import Project, NoProject, _realpath
+from ropetest import testutils
+from rope.base.resourceobserver import ResourceObserver, FilteredResourceObserver
+
+
+
+class ProjectTest(unittest.TestCase):
+
+    def setUp(self):
+        unittest.TestCase.setUp(self)
+        self.project = testutils.sample_project(foldername='sampleproject',
+                                                ropefolder=None)
+        self.project_root = self.project.address
+        self._make_sample_project()
+        self.no_project = NoProject()
+
+    def _make_sample_project(self):
+        self.sample_file = 'sample_file.txt'
+        self.sample_path = os.path.join(self.project_root, 'sample_file.txt')
+        if not os.path.exists(self.project_root):
+            os.mkdir(self.project_root)
+        self.sample_folder = 'sample_folder'
+        os.mkdir(os.path.join(self.project_root, self.sample_folder))
+        sample = open(self.sample_path, 'w')
+        sample.write('sample text\n')
+        sample.close()
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        unittest.TestCase.tearDown(self)
+
+    def test_project_creation(self):
+        self.assertEquals(_realpath(self.project_root),
+                          self.project.address)
+
+    def test_getting_project_file(self):
+        project_file = self.project.get_resource(self.sample_file)
+        self.assertTrue(project_file is not None)
+
+    def test_project_file_reading(self):
+        projectFile = self.project.get_resource(self.sample_file)
+        self.assertEquals('sample text\n', projectFile.read())
+
+    @testutils.assert_raises(ResourceNotFoundError)
+    def test_getting_not_existing_project_file(self):
+        projectFile = self.project.get_resource('DoesNotExistFile.txt')
+        self.fail('Should have failed')
+
+    def test_writing_in_project_files(self):
+        project_file = self.project.get_resource(self.sample_file)
+        project_file.write('another text\n')
+        self.assertEquals('another text\n', project_file.read())
+
+    def test_creating_files(self):
+        project_file = 'newfile.txt'
+        self.project.root.create_file(project_file)
+        newFile = self.project.get_resource(project_file)
+        self.assertTrue(newFile is not None)
+
+    @testutils.assert_raises(RopeError)
+    def test_creating_files_that_already_exist(self):
+        self.project.root.create_file(self.sample_file)
+        self.fail('Should have failed')
+
+    def test_making_root_folder_if_it_does_not_exist(self):
+        project = Project('sampleproject2')
+        try:
+            self.assertTrue(os.path.exists('sampleproject2') and
+                            os.path.isdir('sampleproject2'))
+        finally:
+            testutils.remove_project(project)
+
+    @testutils.assert_raises(RopeError)
+    def test_failure_when_project_root_exists_and_is_a_file(self):
+        try:
+            project_root = 'sampleproject2'
+            open(project_root, 'w').close()
+            project = Project(project_root)
+        finally:
+            testutils.remove_recursively(project_root)
+
+    def test_creating_folders(self):
+        folderName = 'SampleFolder'
+        self.project.root.create_folder(folderName)
+        folderPath = os.path.join(self.project.address, folderName)
+        self.assertTrue(os.path.exists(folderPath) and os.path.isdir(folderPath))
+
+    @testutils.assert_raises(RopeError)
+    def test_making_folder_that_already_exists(self):
+        folderName = 'SampleFolder'
+        self.project.root.create_folder(folderName)
+        self.project.root.create_folder(folderName)
+
+    @testutils.assert_raises(RopeError)
+    def test_failing_if_creating_folder_while_file_already_exists(self):
+        folderName = 'SampleFolder'
+        self.project.root.create_file(folderName)
+        self.project.root.create_folder(folderName)
+
+    def test_creating_file_inside_folder(self):
+        folder_name = 'sampleFolder'
+        file_name = 'sample2.txt'
+        file_path = folder_name + '/' + file_name
+        parent_folder = self.project.root.create_folder(folder_name)
+        parent_folder.create_file(file_name)
+        file = self.project.get_resource(file_path)
+        file.write('sample notes')
+        self.assertEquals(file_path, file.path)
+        self.assertEquals('sample notes', open(os.path.join(self.project.address,
+                                                            file_path)).read())
+
+    @testutils.assert_raises(ResourceNotFoundError)
+    def test_failing_when_creating_file_inside_non_existent_folder(self):
+        self.project.root.create_file('NonexistentFolder/SomeFile.txt')
+
+    def test_nested_directories(self):
+        folder_name = 'SampleFolder'
+        parent = self.project.root.create_folder(folder_name)
+        parent.create_folder(folder_name)
+        folder_path = os.path.join(self.project.address, folder_name, folder_name)
+        self.assertTrue(os.path.exists(folder_path) and os.path.isdir(folder_path))
+
+    def test_removing_files(self):
+        self.assertTrue(os.path.exists(self.sample_path))
+        self.project.get_resource(self.sample_file).remove()
+        self.assertFalse(os.path.exists(self.sample_path))
+
+    def test_removing_files_invalidating_in_project_resource_pool(self):
+        root_folder = self.project.root
+        my_file = root_folder.create_file('my_file.txt')
+        my_file.remove()
+        self.assertFalse(root_folder.has_child('my_file.txt'))
+
+    def test_removing_directories(self):
+        self.assertTrue(os.path.exists(os.path.join(self.project.address,
+                                                    self.sample_folder)))
+        self.project.get_resource(self.sample_folder).remove()
+        self.assertFalse(os.path.exists(os.path.join(self.project.address,
+                                                     self.sample_folder)))
+
+    @testutils.assert_raises(ResourceNotFoundError)
+    def test_removing_non_existent_files(self):
+        self.project.get_resource('NonExistentFile.txt').remove()
+
+    def test_removing_nested_files(self):
+        file_name = self.sample_folder + '/sample_file.txt'
+        self.project.root.create_file(file_name)
+        self.project.get_resource(file_name).remove()
+        self.assertTrue(os.path.exists(os.path.join(self.project.address,
+                                                    self.sample_folder)))
+        self.assertTrue(not os.path.exists(os.path.join(self.project.address,
+                                  file_name)))
+
+    def test_file_get_name(self):
+        file = self.project.get_resource(self.sample_file)
+        self.assertEquals(self.sample_file, file.name)
+        file_name = 'nestedFile.txt'
+        parent = self.project.get_resource(self.sample_folder)
+        filePath = self.sample_folder + '/' + file_name
+        parent.create_file(file_name)
+        nestedFile = self.project.get_resource(filePath)
+        self.assertEquals(file_name, nestedFile.name)
+
+    def test_folder_get_name(self):
+        folder = self.project.get_resource(self.sample_folder)
+        self.assertEquals(self.sample_folder, folder.name)
+
+    def test_file_get_path(self):
+        file = self.project.get_resource(self.sample_file)
+        self.assertEquals(self.sample_file, file.path)
+        fileName = 'nestedFile.txt'
+        parent = self.project.get_resource(self.sample_folder)
+        filePath = self.sample_folder + '/' + fileName
+        parent.create_file(fileName)
+        nestedFile = self.project.get_resource(filePath)
+        self.assertEquals(filePath, nestedFile.path)
+
+    def test_folder_get_path(self):
+        folder = self.project.get_resource(self.sample_folder)
+        self.assertEquals(self.sample_folder, folder.path)
+
+    def test_is_folder(self):
+        self.assertTrue(self.project.get_resource(self.sample_folder).is_folder())
+        self.assertTrue(not self.project.get_resource(self.sample_file).is_folder())
+
+    def testget_children(self):
+        children = self.project.get_resource(self.sample_folder).get_children()
+        self.assertEquals([], children)
+
+    def test_nonempty_get_children(self):
+        file_name = 'nestedfile.txt'
+        filePath = self.sample_folder + '/' + file_name
+        parent = self.project.get_resource(self.sample_folder)
+        parent.create_file(file_name)
+        children = parent.get_children()
+        self.assertEquals(1, len(children))
+        self.assertEquals(filePath, children[0].path)
+
+    def test_nonempty_get_children2(self):
+        file_name = 'nestedfile.txt'
+        folder_name = 'nestedfolder.txt'
+        filePath = self.sample_folder + '/' + file_name
+        folderPath = self.sample_folder + '/' + folder_name
+        parent = self.project.get_resource(self.sample_folder)
+        parent.create_file(file_name)
+        parent.create_folder(folder_name)
+        children = parent.get_children()
+        self.assertEquals(2, len(children))
+        self.assertTrue(filePath == children[0].path or filePath == children[1].path)
+        self.assertTrue(folderPath == children[0].path or folderPath == children[1].path)
+
+    def test_getting_files(self):
+        files = self.project.root.get_files()
+        self.assertEquals(1, len(files))
+        self.assertTrue(self.project.get_resource(self.sample_file) in files)
+
+    def test_getting_folders(self):
+        folders = self.project.root.get_folders()
+        self.assertEquals(1, len(folders))
+        self.assertTrue(self.project.get_resource(self.sample_folder) in folders)
+
+    def test_nested_folder_get_files(self):
+        parent = self.project.root.create_folder('top')
+        parent.create_file('file1.txt')
+        parent.create_file('file2.txt')
+        files = parent.get_files()
+        self.assertEquals(2, len(files))
+        self.assertTrue(self.project.get_resource('top/file2.txt') in files)
+        self.assertEquals(0, len(parent.get_folders()))
+
+    def test_nested_folder_get_folders(self):
+        parent = self.project.root.create_folder('top')
+        parent.create_folder('dir1')
+        parent.create_folder('dir2')
+        folders = parent.get_folders()
+        self.assertEquals(2, len(folders))
+        self.assertTrue(self.project.get_resource('top/dir1') in folders)
+        self.assertEquals(0, len(parent.get_files()))
+
+    def test_root_folder(self):
+        root_folder = self.project.root
+        self.assertEquals(2, len(root_folder.get_children()))
+        self.assertEquals('', root_folder.path)
+        self.assertEquals('', root_folder.name)
+
+    def test_get_all_files(self):
+        files = tuple(self.project.get_files())
+        self.assertEquals(1, len(files))
+        self.assertEquals(self.sample_file, files[0].name)
+
+    def test_get_all_files_after_changing(self):
+        self.assertEquals(1, len(self.project.get_files()))
+        myfile = self.project.root.create_file('myfile.txt')
+        self.assertEquals(2, len(self.project.get_files()))
+        myfile.move('newfile.txt')
+        self.assertEquals(2, len(self.project.get_files()))
+        self.project.get_file('newfile.txt').remove()
+        self.assertEquals(1, len(self.project.get_files()))
+
+    def test_multifile_get_all_files(self):
+        fileName = 'nestedFile.txt'
+        parent = self.project.get_resource(self.sample_folder)
+        parent.create_file(fileName)
+        files = list(self.project.get_files())
+        self.assertEquals(2, len(files))
+        self.assertTrue(fileName == files[0].name or fileName == files[1].name)
+
+    def test_ignoring_dot_pyc_files_in_get_files(self):
+        root = self.project.address
+        src_folder = os.path.join(root, 'src')
+        os.mkdir(src_folder)
+        test_pyc = os.path.join(src_folder, 'test.pyc')
+        file(test_pyc, 'w').close()
+        for x in self.project.get_files():
+            self.assertNotEquals('src/test.pyc', x.path)
+
+    def test_folder_creating_files(self):
+        projectFile = 'NewFile.txt'
+        self.project.root.create_file(projectFile)
+        new_file = self.project.get_resource(projectFile)
+        self.assertTrue(new_file is not None and not new_file.is_folder())
+
+    def test_folder_creating_nested_files(self):
+        project_file = 'NewFile.txt'
+        parent_folder = self.project.get_resource(self.sample_folder)
+        parent_folder.create_file(project_file)
+        new_file = self.project.get_resource(self.sample_folder
+                                            + '/' + project_file)
+        self.assertTrue(new_file is not None and not new_file.is_folder())
+
+    def test_folder_creating_files2(self):
+        projectFile = 'newfolder'
+        self.project.root.create_folder(projectFile)
+        new_folder = self.project.get_resource(projectFile)
+        self.assertTrue(new_folder is not None and new_folder.is_folder())
+
+    def test_folder_creating_nested_files2(self):
+        project_file = 'newfolder'
+        parent_folder = self.project.get_resource(self.sample_folder)
+        parent_folder.create_folder(project_file)
+        new_folder = self.project.get_resource(self.sample_folder
+                                               + '/' + project_file)
+        self.assertTrue(new_folder is not None and new_folder.is_folder())
+
+    def test_folder_get_child(self):
+        folder = self.project.root
+        folder.create_file('myfile.txt')
+        folder.create_folder('myfolder')
+        self.assertEquals(self.project.get_resource('myfile.txt'),
+                          folder.get_child('myfile.txt'))
+        self.assertEquals(self.project.get_resource('myfolder'),
+                          folder.get_child('myfolder'))
+
+    def test_folder_get_child_nested(self):
+        root = self.project.root
+        folder = root.create_folder('myfolder')
+        folder.create_file('myfile.txt')
+        folder.create_folder('myfolder')
+        self.assertEquals(self.project.get_resource('myfolder/myfile.txt'),
+                          folder.get_child('myfile.txt'))
+        self.assertEquals(self.project.get_resource('myfolder/myfolder'),
+                          folder.get_child('myfolder'))
+
+    def test_project_root_is_root_folder(self):
+        self.assertEquals('', self.project.root.path)
+
+    def test_moving_files(self):
+        root_folder = self.project.root
+        my_file = root_folder.create_file('my_file.txt')
+        my_file.move('my_other_file.txt')
+        self.assertFalse(my_file.exists())
+        root_folder.get_child('my_other_file.txt')
+
+    def test_moving_folders(self):
+        root_folder = self.project.root
+        my_folder = root_folder.create_folder('my_folder')
+        my_file = my_folder.create_file('my_file.txt')
+        my_folder.move('new_folder')
+        self.assertFalse(root_folder.has_child('my_folder'))
+        self.assertFalse(my_file.exists())
+        self.assertTrue(root_folder.get_child('new_folder') is not None)
+
+    def test_moving_destination_folders(self):
+        root_folder = self.project.root
+        my_folder = root_folder.create_folder('my_folder')
+        my_file = root_folder.create_file('my_file.txt')
+        my_file.move('my_folder')
+        self.assertFalse(root_folder.has_child('my_file.txt'))
+        self.assertFalse(my_file.exists())
+        my_folder.get_child('my_file.txt')
+
+    def test_moving_files_and_resource_objects(self):
+        root_folder = self.project.root
+        my_file = root_folder.create_file('my_file.txt')
+        old_hash = hash(my_file)
+        my_file.move('my_other_file.txt')
+        self.assertEquals(old_hash, hash(my_file))
+
+    def test_file_encoding_reading(self):
+        sample_file = self.project.root.create_file('my_file.txt')
+        contents = u'# -*- coding: utf-8 -*-\n#\N{LATIN SMALL LETTER I WITH DIAERESIS}\n'
+        file = open(sample_file.real_path, 'w')
+        file.write(contents.encode('utf-8'))
+        file.close()
+        self.assertEquals(contents, sample_file.read())
+
+    def test_file_encoding_writing(self):
+        sample_file = self.project.root.create_file('my_file.txt')
+        contents = u'# -*- coding: utf-8 -*-\n\N{LATIN SMALL LETTER I WITH DIAERESIS}\n'
+        sample_file.write(contents)
+        self.assertEquals(contents, sample_file.read())
+
+    def test_using_utf8_when_writing_in_case_of_errors(self):
+        sample_file = self.project.root.create_file('my_file.txt')
+        contents = u'\n\N{LATIN SMALL LETTER I WITH DIAERESIS}\n'
+        sample_file.write(contents)
+        self.assertEquals(contents, sample_file.read())
+
+    def test_encoding_declaration_in_the_second_line(self):
+        sample_file = self.project.root.create_file('my_file.txt')
+        contents = '\n# -*- coding: latin-1 -*-\n\xa9\n'
+        file = open(sample_file.real_path, 'wb')
+        file.write(contents)
+        file.close()
+        self.assertEquals(contents, sample_file.read().encode('latin-1'))
+
+    def test_read_bytes(self):
+        sample_file = self.project.root.create_file('my_file.txt')
+        contents = '\n# -*- coding: latin-1 -*-\n\xa9\n'
+        file = open(sample_file.real_path, 'wb')
+        file.write(contents)
+        file.close()
+        self.assertEquals(contents, sample_file.read_bytes())
+
+    # TODO: Detecting utf-16 encoding
+    def xxx_test_using_utf16(self):
+        sample_file = self.project.root.create_file('my_file.txt')
+        contents = '# -*- coding: utf-16 -*-\n# This is a sample file ...\n'
+        file = open(sample_file.real_path, 'w')
+        file.write(contents.encode('utf-16'))
+        file.close()
+        sample_file.write(contents)
+        self.assertEquals(contents, sample_file.read())
+
+    # XXX: supporting utf_8_sig
+    def xxx_test_file_encoding_reading_for_notepad_styles(self):
+        sample_file = self.project.root.create_file('my_file.txt')
+        contents = u'#\N{LATIN SMALL LETTER I WITH DIAERESIS}\n'
+        file = open(sample_file.real_path, 'w')
+        # file.write('\xef\xbb\xbf')
+        file.write(contents.encode('utf-8-sig'))
+        file.close()
+        self.assertEquals(contents, sample_file.read())
+
+    def test_using_project_get_file(self):
+        myfile = self.project.get_file(self.sample_file)
+        self.assertTrue(myfile.exists())
+
+    def test_using_file_create(self):
+        myfile = self.project.get_file('myfile.txt')
+        self.assertFalse(myfile.exists())
+        myfile.create()
+        self.assertTrue(myfile.exists())
+        self.assertFalse(myfile.is_folder())
+
+    def test_using_folder_create(self):
+        myfolder = self.project.get_folder('myfolder')
+        self.assertFalse(myfolder.exists())
+        myfolder.create()
+        self.assertTrue(myfolder.exists())
+        self.assertTrue(myfolder.is_folder())
+
+    @testutils.assert_raises(RopeError)
+    def test_exception_when_creating_twice(self):
+        myfile = self.project.get_file('myfile.txt')
+        myfile.create()
+        myfile.create()
+
+    @testutils.assert_raises(ResourceNotFoundError)
+    def test_exception_when_parent_does_not_exist(self):
+        myfile = self.project.get_file('myfolder/myfile.txt')
+        myfile.create()
+
+    def test_simple_path_to_resource(self):
+        myfile = self.project.root.create_file('myfile.txt')
+        self.assertEquals(myfile, path_to_resource(self.project,
+                                                   myfile.real_path))
+        self.assertEquals(myfile, path_to_resource(
+                          self.project, myfile.real_path, type='file'))
+        myfolder = self.project.root.create_folder('myfolder')
+        self.assertEquals(myfolder, path_to_resource(self.project,
+                                                     myfolder.real_path))
+        self.assertEquals(myfolder, path_to_resource(
+                          self.project, myfolder.real_path, type='folder'))
+
+    @testutils.run_only_for_unix
+    def test_ignoring_symlinks_inside_project(self):
+        project2 = testutils.sample_project(folder_name='sampleproject2')
+        mod = project2.root.create_file('mod.py')
+        try:
+            path = os.path.join(self.project.address, 'linkedfile.txt')
+            os.symlink(mod.real_path, path)
+            files = self.project.root.get_files()
+            self.assertEquals(1, len(files))
+        finally:
+            testutils.remove_project(project2)
+
+
+class ResourceObserverTest(unittest.TestCase):
+
+    def setUp(self):
+        super(ResourceObserverTest, self).setUp()
+        self.project = testutils.sample_project()
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(ResourceObserverTest, self).tearDown()
+
+    def test_resource_change_observer(self):
+        sample_file = self.project.root.create_file('my_file.txt')
+        sample_file.write('a sample file version 1')
+        sample_observer = _SampleObserver()
+        self.project.add_observer(sample_observer)
+        sample_file.write('a sample file version 2')
+        self.assertEquals(1, sample_observer.change_count)
+        self.assertEquals(sample_file, sample_observer.last_changed)
+
+    def test_resource_change_observer_after_removal(self):
+        sample_file = self.project.root.create_file('my_file.txt')
+        sample_file.write('text')
+        sample_observer = _SampleObserver()
+        self.project.add_observer(FilteredResourceObserver(sample_observer,
+                                                           [sample_file]))
+        sample_file.remove()
+        self.assertEquals(1, sample_observer.change_count)
+        self.assertEquals(sample_file, sample_observer.last_removed)
+
+    def test_resource_change_observer2(self):
+        sample_file = self.project.root.create_file('my_file.txt')
+        sample_observer = _SampleObserver()
+        self.project.add_observer(sample_observer)
+        self.project.remove_observer(sample_observer)
+        sample_file.write('a sample file version 2')
+        self.assertEquals(0, sample_observer.change_count)
+
+    def test_resource_change_observer_for_folders(self):
+        root_folder = self.project.root
+        my_folder = root_folder.create_folder('my_folder')
+        my_folder_observer = _SampleObserver()
+        root_folder_observer = _SampleObserver()
+        self.project.add_observer(FilteredResourceObserver(my_folder_observer,
+                                                           [my_folder]))
+        self.project.add_observer(FilteredResourceObserver(root_folder_observer,
+                                                           [root_folder]))
+        my_file = my_folder.create_file('my_file.txt')
+        self.assertEquals(1, my_folder_observer.change_count)
+        my_file.move('another_file.txt')
+        self.assertEquals(2, my_folder_observer.change_count)
+        self.assertEquals(1, root_folder_observer.change_count)
+        self.project.get_resource('another_file.txt').remove()
+        self.assertEquals(2, my_folder_observer.change_count)
+        self.assertEquals(2, root_folder_observer.change_count)
+
+    def test_resource_change_observer_after_moving(self):
+        sample_file = self.project.root.create_file('my_file.txt')
+        sample_observer = _SampleObserver()
+        self.project.add_observer(sample_observer)
+        sample_file.move('new_file.txt')
+        self.assertEquals(1, sample_observer.change_count)
+        self.assertEquals((sample_file, self.project.get_resource('new_file.txt')),
+                           sample_observer.last_moved)
+
+    def test_revalidating_files(self):
+        root = self.project.root
+        my_file = root.create_file('my_file.txt')
+        sample_observer = _SampleObserver()
+        self.project.add_observer(FilteredResourceObserver(sample_observer,
+                                                           [my_file]))
+        os.remove(my_file.real_path)
+        self.project.validate(root)
+        self.assertEquals(my_file, sample_observer.last_removed)
+        self.assertEquals(1, sample_observer.change_count)
+
+    def test_revalidating_files_and_no_changes2(self):
+        root = self.project.root
+        my_file = root.create_file('my_file.txt')
+        sample_observer = _SampleObserver()
+        self.project.add_observer(FilteredResourceObserver(sample_observer,
+                                                           [my_file]))
+        self.project.validate(root)
+        self.assertEquals(None, sample_observer.last_moved)
+        self.assertEquals(0, sample_observer.change_count)
+
+    def test_revalidating_folders(self):
+        root = self.project.root
+        my_folder = root.create_folder('myfolder')
+        my_file = my_folder.create_file('myfile.txt')
+        sample_observer = _SampleObserver()
+        self.project.add_observer(FilteredResourceObserver(sample_observer,
+                                                           [my_folder]))
+        testutils.remove_recursively(my_folder.real_path)
+        self.project.validate(root)
+        self.assertEquals(my_folder, sample_observer.last_removed)
+        self.assertEquals(1, sample_observer.change_count)
+
+    def test_removing_and_adding_resources_to_filtered_observer(self):
+        my_file = self.project.root.create_file('my_file.txt')
+        sample_observer = _SampleObserver()
+        filtered_observer = FilteredResourceObserver(sample_observer)
+        self.project.add_observer(filtered_observer)
+        my_file.write('1')
+        self.assertEquals(0, sample_observer.change_count)
+        filtered_observer.add_resource(my_file)
+        my_file.write('2')
+        self.assertEquals(1, sample_observer.change_count)
+        filtered_observer.remove_resource(my_file)
+        my_file.write('3')
+        self.assertEquals(1, sample_observer.change_count)
+
+    def test_validation_and_changing_files(self):
+        my_file = self.project.root.create_file('my_file.txt')
+        sample_observer = _SampleObserver()
+        timekeeper = _MockChangeIndicator()
+        filtered_observer = FilteredResourceObserver(sample_observer, [my_file],
+                                                     timekeeper=timekeeper)
+        self.project.add_observer(filtered_observer)
+        self._write_file(my_file.real_path)
+        timekeeper.set_indicator(my_file, 1)
+        self.project.validate(self.project.root)
+        self.assertEquals(1, sample_observer.change_count)
+
+    def test_validation_and_changing_files2(self):
+        my_file = self.project.root.create_file('my_file.txt')
+        sample_observer = _SampleObserver()
+        timekeeper = _MockChangeIndicator()
+        self.project.add_observer(FilteredResourceObserver(
+                                  sample_observer, [my_file],
+                                  timekeeper=timekeeper))
+        timekeeper.set_indicator(my_file, 1)
+        my_file.write('hey')
+        self.assertEquals(1, sample_observer.change_count)
+        self.project.validate(self.project.root)
+        self.assertEquals(1, sample_observer.change_count)
+
+    def test_not_reporting_multiple_changes_to_folders(self):
+        root = self.project.root
+        file1 = root.create_file('file1.txt')
+        file2 = root.create_file('file2.txt')
+        sample_observer = _SampleObserver()
+        self.project.add_observer(FilteredResourceObserver(
+                                  sample_observer, [root, file1, file2]))
+        os.remove(file1.real_path)
+        os.remove(file2.real_path)
+        self.assertEquals(0, sample_observer.change_count)
+        self.project.validate(self.project.root)
+        self.assertEquals(3, sample_observer.change_count)
+
+    def _write_file(self, path):
+        my_file = open(path, 'w')
+        my_file.write('\n')
+        my_file.close()
+
+    def test_moving_and_being_interested_about_a_folder_and_a_child(self):
+        my_folder = self.project.root.create_folder('my_folder')
+        my_file = my_folder.create_file('my_file.txt')
+        sample_observer = _SampleObserver()
+        filtered_observer = FilteredResourceObserver(
+            sample_observer, [my_folder, my_file])
+        self.project.add_observer(filtered_observer)
+        my_folder.move('new_folder')
+        self.assertEquals(2, sample_observer.change_count)
+
+    def test_contains_for_folders(self):
+        folder1 = self.project.root.create_folder('folder')
+        folder2 = self.project.root.create_folder('folder2')
+        self.assertFalse(folder1.contains(folder2))
+
+    def test_validating_when_created(self):
+        root = self.project.root
+        my_file = self.project.get_file('my_file.txt')
+        sample_observer = _SampleObserver()
+        self.project.add_observer(FilteredResourceObserver(sample_observer,
+                                                           [my_file]))
+        file(my_file.real_path, 'w').close()
+        self.project.validate(root)
+        self.assertEquals(my_file, sample_observer.last_created)
+        self.assertEquals(1, sample_observer.change_count)
+
+    def test_validating_twice_when_created(self):
+        root = self.project.root
+        my_file = self.project.get_file('my_file.txt')
+        sample_observer = _SampleObserver()
+        self.project.add_observer(FilteredResourceObserver(sample_observer,
+                                                           [my_file]))
+        file(my_file.real_path, 'w').close()
+        self.project.validate(root)
+        self.project.validate(root)
+        self.assertEquals(my_file, sample_observer.last_created)
+        self.assertEquals(1, sample_observer.change_count)
+
+    def test_changes_and_adding_resources(self):
+        root = self.project.root
+        file1 = self.project.get_file('file1.txt')
+        file2 = self.project.get_file('file2.txt')
+        file1.create()
+        sample_observer = _SampleObserver()
+        self.project.add_observer(FilteredResourceObserver(sample_observer,
+                                                           [file1, file2]))
+        file1.move(file2.path)
+        self.assertEquals(2, sample_observer.change_count)
+        self.assertEquals(file2, sample_observer.last_created)
+        self.assertEquals((file1, file2), sample_observer.last_moved)
+
+    def test_validating_get_files_list(self):
+        root = self.project.root
+        self.assertEquals(0, len(self.project.get_files()))
+        file = open(os.path.join(self.project.address, 'myfile.txt'), 'w')
+        file.close()
+        self.project.validate()
+        self.assertEquals(1, len(self.project.get_files()))
+
+    def test_clear_observered_resources_for_filtered_observers(self):
+        sample_file = self.project.root.create_file('myfile.txt')
+        sample_observer = _SampleObserver()
+        filtered = FilteredResourceObserver(sample_observer)
+        self.project.add_observer(filtered)
+        filtered.add_resource(sample_file)
+        filtered.clear_resources()
+        sample_file.write('1')
+        self.assertEquals(0, sample_observer.change_count)
+
+
+class _MockChangeIndicator(object):
+
+    def __init__(self):
+        self.times = {}
+
+    def set_indicator(self, resource, time):
+        self.times[resource] = time
+
+    def get_indicator(self, resource):
+        return self.times.get(resource, 0)
+
+
+class _SampleObserver(object):
+
+    def __init__(self):
+        self.change_count = 0
+        self.last_changed = None
+        self.last_moved = None
+        self.last_created = None
+        self.last_removed = None
+
+    def resource_changed(self, resource):
+        self.last_changed = resource
+        self.change_count += 1
+
+    def resource_moved(self, resource, new_resource):
+        self.last_moved = (resource, new_resource)
+        self.change_count += 1
+
+    def resource_created(self, resource):
+        self.last_created = resource
+        self.change_count += 1
+
+    def resource_removed(self, resource):
+        self.last_removed = resource
+        self.change_count += 1
+
+
+class OutOfProjectTest(unittest.TestCase):
+
+    def setUp(self):
+        super(OutOfProjectTest, self).setUp()
+        self.test_directory = 'temp_test_directory'
+        testutils.remove_recursively(self.test_directory)
+        os.mkdir(self.test_directory)
+        self.project = testutils.sample_project()
+        self.no_project = NoProject()
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        testutils.remove_recursively(self.test_directory)
+        super(OutOfProjectTest, self).tearDown()
+
+    def test_simple_out_of_project_file(self):
+        sample_file_path = os.path.join(self.test_directory, 'sample.txt')
+        sample_file = file(sample_file_path, 'w')
+        sample_file.write('sample content\n')
+        sample_file.close()
+        sample_resource = self.no_project.get_resource(sample_file_path)
+        self.assertEquals('sample content\n', sample_resource.read())
+
+    def test_simple_out_of_project_folder(self):
+        sample_folder_path = os.path.join(self.test_directory, 'sample_folder')
+        os.mkdir(sample_folder_path)
+        sample_folder = self.no_project.get_resource(sample_folder_path)
+        self.assertEquals([], sample_folder.get_children())
+
+        sample_file_path = os.path.join(sample_folder_path, 'sample.txt')
+        file(sample_file_path, 'w').close()
+        sample_resource = self.no_project.get_resource(sample_file_path)
+        self.assertEquals(sample_resource, sample_folder.get_children()[0])
+
+    def test_using_absolute_path(self):
+        sample_file_path = os.path.join(self.test_directory, 'sample.txt')
+        file(sample_file_path, 'w').close()
+        normal_sample_resource = self.no_project.get_resource(sample_file_path)
+        absolute_sample_resource = \
+            self.no_project.get_resource(os.path.abspath(sample_file_path))
+        self.assertEquals(normal_sample_resource, absolute_sample_resource)
+
+    def test_folder_get_child(self):
+        sample_folder_path = os.path.join(self.test_directory, 'sample_folder')
+        os.mkdir(sample_folder_path)
+        sample_folder = self.no_project.get_resource(sample_folder_path)
+        self.assertEquals([], sample_folder.get_children())
+
+        sample_file_path = os.path.join(sample_folder_path, 'sample.txt')
+        file(sample_file_path, 'w').close()
+        sample_resource = self.no_project.get_resource(sample_file_path)
+        self.assertTrue(sample_folder.has_child('sample.txt'))
+        self.assertFalse(sample_folder.has_child('doesnothave.txt'))
+        self.assertEquals(sample_resource, sample_folder.get_child('sample.txt'))
+
+    def test_out_of_project_files_and_path_to_resource(self):
+        sample_file_path = os.path.join(self.test_directory, 'sample.txt')
+        sample_file = file(sample_file_path, 'w')
+        sample_file.write('sample content\n')
+        sample_file.close()
+        sample_resource = self.no_project.get_resource(sample_file_path)
+        self.assertEquals(sample_resource,
+                          path_to_resource(self.project, sample_file_path))
+
+
+class _MockFSCommands(object):
+    
+    def __init__(self):
+        self.log = ''
+        self.fscommands = FileSystemCommands()
+
+    def create_file(self, path):
+        self.log += 'create_file '
+        self.fscommands.create_file(path)
+
+    def create_folder(self, path):
+        self.log += 'create_folder '
+        self.fscommands.create_folder(path)
+
+    def move(self, path, new_location):
+        self.log += 'move '
+        self.fscommands.move(path, new_location)
+
+    def remove(self, path):
+        self.log += 'remove '
+        self.fscommands.remove(path)
+
+
+class RopeFolderTest(unittest.TestCase):
+
+    def setUp(self):
+        super(RopeFolderTest, self).setUp()
+        self.project = None
+
+    def tearDown(self):
+        if self.project:
+            testutils.remove_project(self.project)
+        super(RopeFolderTest, self).tearDown()
+
+    def test_none_project_rope_folder(self):
+        self.project = testutils.sample_project(ropefolder=None)
+        self.assertTrue(self.project.ropefolder is None)
+
+    def test_getting_project_rope_folder(self):
+        self.project = testutils.sample_project(ropefolder='.ropeproject')
+        self.assertTrue(self.project.ropefolder.exists())
+        self.assertTrue('.ropeproject', self.project.ropefolder.path)
+
+    def test_setting_ignored_resources(self):
+        self.project = testutils.sample_project(ignored_resources=['myfile.txt'])
+        myfile = self.project.get_file('myfile.txt')
+        file2 = self.project.get_file('file2.txt')
+        self.assertTrue(self.project.is_ignored(myfile))
+        self.assertFalse(self.project.is_ignored(file2))
+
+    def test_ignored_folders(self):
+        self.project = testutils.sample_project(ignored_resources=['myfolder'])
+        myfolder = self.project.root.create_folder('myfolder')
+        self.assertTrue(self.project.is_ignored(myfolder))
+        myfile = myfolder.create_file('myfile.txt')
+        self.assertTrue(self.project.is_ignored(myfile))
+
+    def test_ignored_resources_and_get_files(self):
+        self.project = testutils.sample_project(
+            ignored_resources=['myfile.txt'], ropefolder=None)
+        myfile = self.project.get_file('myfile.txt')
+        self.assertEquals(0, len(self.project.get_files()))
+        myfile.create()
+        self.assertEquals(0, len(self.project.get_files()))
+
+    def test_ignored_resources_and_get_files2(self):
+        self.project = testutils.sample_project(
+            ignored_resources=['myfile.txt'], ropefolder=None)
+        myfile = self.project.root.create_file('myfile.txt')
+        self.assertEquals(0, len(self.project.get_files()))
+
+    def test_setting_ignored_resources_patterns(self):
+        self.project = testutils.sample_project(ignored_resources=['m?file.*'])
+        myfile = self.project.get_file('myfile.txt')
+        file2 = self.project.get_file('file2.txt')
+        self.assertTrue(self.project.is_ignored(myfile))
+        self.assertFalse(self.project.is_ignored(file2))
+
+    def test_star_should_not_include_slashes(self):
+        self.project = testutils.sample_project(ignored_resources=['f*.txt'])
+        folder = self.project.root.create_folder('folder')
+        file1 = folder.create_file('myfile.txt')
+        file2 = folder.create_file('file2.txt')
+        self.assertFalse(self.project.is_ignored(file1))
+        self.assertTrue(self.project.is_ignored(file2))
+
+    def test_normal_fscommands(self):
+        fscommands = _MockFSCommands()
+        self.project = testutils.sample_project(fscommands=fscommands)
+        myfile = self.project.get_file('myfile.txt')
+        myfile.create()
+        self.assertTrue('create_file ', fscommands.log)
+
+    def test_fscommands_and_ignored_resources(self):
+        fscommands = _MockFSCommands()
+        self.project = testutils.sample_project(
+            fscommands=fscommands, ignored_resources=['myfile.txt'], ropefolder=None)
+        myfile = self.project.get_file('myfile.txt')
+        myfile.create()
+        self.assertEquals('', fscommands.log)
+
+    def test_ignored_resources_and_prefixes(self):
+        self.project = testutils.sample_project(
+            ignored_resources=['.hg'])
+        myfile = self.project.root.create_file('.hgignore')
+        self.assertFalse(self.project.is_ignored(myfile))
+
+    def test_loading_config_dot_py(self):
+        self.project = testutils.sample_project(ropefolder='.ropeproject')
+        config = self.project.get_file('.ropeproject/config.py')
+        if not config.exists():
+            config.create()
+        config.write('def set_prefs(prefs):\n'
+                     '    prefs["ignored_resources"] = ["myfile.txt"]\n'
+                     'def project_opened(project):\n'
+                     '    project.root.create_file("loaded")\n')
+        self.project.close()
+        self.project = Project(self.project.address, ropefolder='.ropeproject')
+        self.assertTrue(self.project.get_file('loaded').exists())
+        myfile = self.project.get_file('myfile.txt')
+        self.assertTrue(self.project.is_ignored(myfile))
+
+    def test_ignoring_syntax_errors(self):
+        self.project = testutils.sample_project(ropefolder=None,
+                                                ignore_syntax_errors=True)
+        pycore = self.project.pycore
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('xyz print')
+        pymod = pycore.resource_to_pyobject(mod)
+
+    def test_compressed_history(self):
+        self.project = testutils.sample_project(compress_history=True)
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('')
+
+    def test_compressed_objectdb(self):
+        self.project = testutils.sample_project(compress_objectdb=True)
+        mod = testutils.create_module(self.project, 'mod')
+        self.project.pycore.analyze_module(mod)
+
+    def test_nested_dot_ropeproject_folder(self):
+        self.project = testutils.sample_project(ropefolder='.f1/f2')
+        ropefolder = self.project.ropefolder
+        self.assertEquals('.f1/f2', ropefolder.path)
+        self.assertTrue(ropefolder.exists())
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(ProjectTest))
+    result.addTests(unittest.makeSuite(ResourceObserverTest))
+    result.addTests(unittest.makeSuite(OutOfProjectTest))
+    result.addTests(unittest.makeSuite(RopeFolderTest))
+    return result
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/pycoretest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,1110 @@
+import sys
+import unittest
+
+from rope.base import exceptions
+from rope.base.pycore import _TextChangeDetector
+from rope.base.pyobjects import get_base_type, AbstractFunction
+from ropetest import testutils
+
+
+class PyCoreTest(unittest.TestCase):
+
+    def setUp(self):
+        super(PyCoreTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(PyCoreTest, self).tearDown()
+
+    def test_simple_module(self):
+        testutils.create_module(self.project, 'mod')
+        result = self.pycore.get_module('mod')
+        self.assertEquals(get_base_type('Module'), result.type)
+        self.assertEquals(0, len(result.get_attributes()))
+
+    def test_nested_modules(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod = testutils.create_module(self.project, 'mod', pkg)
+        package = self.pycore.get_module('pkg')
+        self.assertEquals(get_base_type('Module'), package.get_type())
+        self.assertEquals(1, len(package.get_attributes()))
+        module = package['mod'].get_object()
+        self.assertEquals(get_base_type('Module'), module.get_type())
+
+    def test_package(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod = testutils.create_module(self.project, 'mod', pkg)
+        result = self.pycore.get_module('pkg')
+        self.assertEquals(get_base_type('Module'), result.type)
+
+    def test_simple_class(self):
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('class SampleClass(object):\n    pass\n')
+        mod_element = self.pycore.get_module('mod')
+        result = mod_element['SampleClass'].get_object()
+        self.assertEquals(get_base_type('Type'), result.get_type())
+
+    def test_simple_function(self):
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('def sample_function():\n    pass\n')
+        mod_element = self.pycore.get_module('mod')
+        result = mod_element['sample_function'].get_object()
+        self.assertEquals(get_base_type('Function'), result.get_type())
+
+    def test_class_methods(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class SampleClass(object):\n' \
+               '    def sample_method(self):\n' \
+               '        pass\n'
+        mod.write(code)
+        mod_element = self.pycore.get_module('mod')
+        sample_class = mod_element['SampleClass'].get_object()
+        self.assertTrue('sample_method' in sample_class)
+        method = sample_class['sample_method'].get_object()
+        self.assertEquals(get_base_type('Function'), method.get_type())
+
+    def test_global_variables(self):
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('var = 10')
+        mod_element = self.pycore.get_module('mod')
+        result = mod_element['var']
+
+    def test_class_variables(self):
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('class SampleClass(object):\n    var = 10\n')
+        mod_element = self.pycore.get_module('mod')
+        sample_class = mod_element['SampleClass'].get_object()
+        var = sample_class['var']
+
+    def test_class_attributes_set_in_init(self):
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('class C(object):\n'
+                  '    def __init__(self):\n        self.var = 20\n')
+        mod_element = self.pycore.get_module('mod')
+        sample_class = mod_element['C'].get_object()
+        var = sample_class['var']
+
+    def test_class_attributes_set_in_init_overwriting_a_defined(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C(object):\n' \
+               '    def __init__(self):\n' \
+               '        self.f = 20\n' \
+               '    def f():\n' \
+               '        pass\n'
+        mod.write(code)
+        mod_element = self.pycore.get_module('mod')
+        sample_class = mod_element['C'].get_object()
+        f = sample_class['f'].get_object()
+        self.assertTrue(isinstance(f, AbstractFunction))
+
+    def test_classes_inside_other_classes(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class SampleClass(object):\n' \
+               '    class InnerClass(object):\n' \
+               '        pass\n\n'
+        mod.write(code)
+        mod_element = self.pycore.get_module('mod')
+        sample_class = mod_element['SampleClass'].get_object()
+        var = sample_class['InnerClass'].get_object()
+        self.assertEquals(get_base_type('Type'), var.get_type())
+
+    @testutils.assert_raises(exceptions.ModuleNotFoundError)
+    def test_non_existent_module(self):
+        self.pycore.get_module('doesnotexistmodule')
+
+    def test_imported_names(self):
+        testutils.create_module(self.project, 'mod1')
+        mod = testutils.create_module(self.project, 'mod2')
+        mod.write('import mod1\n')
+        module = self.pycore.get_module('mod2')
+        imported_sys = module['mod1'].get_object()
+        self.assertEquals(get_base_type('Module'), imported_sys.get_type())
+
+    def test_imported_as_names(self):
+        testutils.create_module(self.project, 'mod1')
+        mod = testutils.create_module(self.project, 'mod2')
+        mod.write('import mod1 as my_import\n')
+        module = self.pycore.get_module('mod2')
+        imported_mod = module['my_import'].get_object()
+        self.assertEquals(get_base_type('Module'), imported_mod.get_type())
+
+    def test_get_string_module(self):
+        mod = self.pycore.get_string_module('class Sample(object):\n    pass\n')
+        sample_class = mod['Sample'].get_object()
+        self.assertEquals(get_base_type('Type'), sample_class.get_type())
+
+    def test_get_string_module_with_extra_spaces(self):
+        mod = self.pycore.get_string_module('a = 10\n    ')
+
+    def test_parameter_info_for_functions(self):
+        code = 'def func(param1, param2=10, *param3, **param4):\n    pass'
+        mod = self.pycore.get_string_module(code)
+        sample_function = mod['func']
+        self.assertEquals(['param1', 'param2', 'param3', 'param4'],
+                          sample_function.get_object().get_param_names())
+
+    # FIXME: Not found modules
+    def xxx_test_not_found_module_is_module(self):
+        mod = self.pycore.get_string_module('import doesnotexist\n')
+        self.assertEquals(get_base_type('Module'),
+                          mod['doesnotexist'].
+                          get_object().get_type())
+
+    def test_mixing_scopes_and_objects_hierarchy(self):
+        mod = self.pycore.get_string_module('var = 200\n')
+        scope = mod.get_scope()
+        self.assertTrue('var' in scope.get_names())
+
+    def test_inheriting_base_class_attributes(self):
+        code = 'class Base(object):\n' \
+               '    def method(self):\n' \
+               '        pass\n' \
+               'class Derived(Base):\n' \
+               '    pass\n'
+        mod = self.pycore.get_string_module(code)
+        derived = mod['Derived'].get_object()
+        self.assertTrue('method' in derived)
+        self.assertEquals(get_base_type('Function'),
+                          derived['method'].get_object().get_type())
+
+    def test_inheriting_multiple_base_class_attributes(self):
+        code = 'class Base1(object):\n    def method1(self):\n        pass\n' \
+               'class Base2(object):\n    def method2(self):\n        pass\n' \
+               'class Derived(Base1, Base2):\n    pass\n'
+        mod = self.pycore.get_string_module(code)
+        derived = mod['Derived'].get_object()
+        self.assertTrue('method1' in derived)
+        self.assertTrue('method2' in derived)
+
+    def test_inheriting_multiple_base_class_attributes_with_the_same_name(self):
+        code = 'class Base1(object):\n    def method(self):\n        pass\n' \
+               'class Base2(object):\n    def method(self):\n        pass\n' \
+               'class Derived(Base1, Base2):\n    pass\n'
+        mod = self.pycore.get_string_module(code)
+        base1 = mod['Base1'].get_object()
+        derived = mod['Derived'].get_object()
+        self.assertEquals(base1['method'].get_object(),
+                          derived['method'].get_object())
+
+    def test_inheriting_unknown_base_class(self):
+        code = 'class Derived(NotFound):\n' \
+               '    def f(self):\n' \
+               '        pass\n'
+        mod = self.pycore.get_string_module(code)
+        derived = mod['Derived'].get_object()
+        self.assertTrue('f' in derived)
+
+    def test_module_creation(self):
+        new_module = testutils.create_module(self.project, 'module')
+        self.assertFalse(new_module.is_folder())
+        self.assertEquals(self.project.get_resource('module.py'), new_module)
+
+    def test_packaged_module_creation(self):
+        package = self.project.root.create_folder('package')
+        new_module = testutils.create_module(self.project, 'package.module')
+        self.assertEquals(self.project.get_resource('package/module.py'), new_module)
+
+    def test_packaged_module_creation_with_nested_src(self):
+        src = self.project.root.create_folder('src')
+        package = src.create_folder('pkg')
+        new_module = testutils.create_module(self.project, 'pkg.mod', src)
+        self.assertEquals(self.project.get_resource('src/pkg/mod.py'), new_module)
+
+    def test_package_creation(self):
+        new_package = testutils.create_package(self.project, 'pkg')
+        self.assertTrue(new_package.is_folder())
+        self.assertEquals(self.project.get_resource('pkg'), new_package)
+        self.assertEquals(self.project.get_resource('pkg/__init__.py'),
+                          new_package.get_child('__init__.py'));
+
+    def test_nested_package_creation(self):
+        package = testutils.create_package(self.project, 'pkg1')
+        nested_package = testutils.create_package(self.project, 'pkg1.pkg2')
+        self.assertEquals(self.project.get_resource('pkg1/pkg2'), nested_package)
+
+    def test_packaged_package_creation_with_nested_src(self):
+        src = self.project.root.create_folder('src')
+        package = testutils.create_package(self.project, 'pkg1', src)
+        nested_package = testutils.create_package(self.project, 'pkg1.pkg2', src)
+        self.assertEquals(self.project.get_resource('src/pkg1/pkg2'), nested_package)
+
+    def test_find_module(self):
+        src = self.project.root.create_folder('src')
+        samplemod = testutils.create_module(self.project, 'samplemod', src)
+        found_module = self.pycore.find_module('samplemod')
+        self.assertEquals(samplemod, found_module)
+
+    def test_find_nested_module(self):
+        src = self.project.root.create_folder('src')
+        samplepkg = testutils.create_package(self.project, 'samplepkg', src)
+        samplemod = testutils.create_module(self.project, 'samplemod', samplepkg)
+        found_module = self.pycore.find_module('samplepkg.samplemod')
+        self.assertEquals(samplemod, found_module)
+
+    def test_find_multiple_module(self):
+        src = self.project.root.create_folder('src')
+        samplemod1 = testutils.create_module(self.project, 'samplemod', src)
+        samplemod2 = testutils.create_module(self.project, 'samplemod')
+        test = self.project.root.create_folder('test')
+        samplemod3 = testutils.create_module(self.project, 'samplemod', test)
+        found_module = self.pycore.find_module('samplemod')
+        self.assertTrue(samplemod1 == found_module or
+                        samplemod2 == found_module or
+                        samplemod3 == found_module)
+
+    def test_find_module_packages(self):
+        src = self.project.root
+        samplepkg = testutils.create_package(self.project, 'samplepkg', src)
+        found_module = self.pycore.find_module('samplepkg')
+        self.assertEquals(samplepkg, found_module)
+
+    def test_find_module_when_module_and_package_with_the_same_name(self):
+        src = self.project.root
+        samplemod = testutils.create_module(self.project, 'sample', src)
+        samplepkg = testutils.create_package(self.project, 'sample', src)
+        found_module = self.pycore.find_module('sample')
+        self.assertEquals(samplepkg, found_module)
+
+    def test_source_folders_preference(self):
+        pkg1 = testutils.create_package(self.project, 'pkg1')
+        src2 = testutils.create_package(self.project, 'pkg1.src2')
+        lost = testutils.create_module(self.project, 'pkg1.src2.lost')
+        self.assertEqual(self.project.pycore.find_module('lost'), None)
+        self.project.close()
+        from rope.base.project import Project
+        self.project = Project(self.project.address,
+                               source_folders=['pkg1/src2'])
+        self.assertEqual(self.project.pycore.find_module('lost'), lost)
+
+    def test_getting_empty_source_folders(self):
+        self.assertEquals([], self.pycore.get_source_folders())
+
+    def test_root_source_folder(self):
+        self.project.root.create_file('sample.py')
+        source_folders = self.pycore.get_source_folders()
+        self.assertEquals(1, len(source_folders))
+        self.assertTrue(self.project.root in source_folders)
+
+    def test_root_source_folder2(self):
+        self.project.root.create_file('mod1.py')
+        self.project.root.create_file('mod2.py')
+        source_folders = self.pycore.get_source_folders()
+        self.assertEquals(1, len(source_folders))
+        self.assertTrue(self.project.root in source_folders)
+
+    def test_src_source_folder(self):
+        src = self.project.root.create_folder('src')
+        src.create_file('sample.py')
+        source_folders = self.pycore.get_source_folders()
+        self.assertEquals(1, len(source_folders))
+        self.assertTrue(self.project.get_resource('src') in source_folders)
+
+    def test_packages(self):
+        src = self.project.root.create_folder('src')
+        pkg = src.create_folder('package')
+        pkg.create_file('__init__.py')
+        source_folders = self.pycore.get_source_folders()
+        self.assertEquals(1, len(source_folders))
+        self.assertTrue(src in source_folders)
+
+    def test_multi_source_folders(self):
+        src = self.project.root.create_folder('src')
+        package = src.create_folder('package')
+        package.create_file('__init__.py')
+        test = self.project.root.create_folder('test')
+        test.create_file('alltests.py')
+        source_folders = self.pycore.get_source_folders()
+        self.assertEquals(2, len(source_folders))
+        self.assertTrue(src in source_folders)
+        self.assertTrue(test in source_folders)
+
+    def test_multi_source_folders2(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        src = self.project.root.create_folder('src')
+        package = testutils.create_package(self.project, 'package', src)
+        mod2 = testutils.create_module(self.project, 'mod2', package)
+        source_folders = self.pycore.get_source_folders()
+        self.assertEquals(2, len(source_folders))
+        self.assertTrue(self.project.root in source_folders and \
+                        src in source_folders)
+
+    def test_get_pyname_definition_location(self):
+        mod = self.pycore.get_string_module('a_var = 20\n')
+        a_var = mod['a_var']
+        self.assertEquals((mod, 1), a_var.get_definition_location())
+
+    def test_get_pyname_definition_location_functions(self):
+        mod = self.pycore.get_string_module('def a_func():\n    pass\n')
+        a_func = mod['a_func']
+        self.assertEquals((mod, 1), a_func.get_definition_location())
+
+    def test_get_pyname_definition_location_class(self):
+        code = 'class AClass(object):\n    pass\n\n'
+        mod = self.pycore.get_string_module(code)
+        a_class = mod['AClass']
+        self.assertEquals((mod, 1), a_class.get_definition_location())
+
+    def test_get_pyname_definition_location_local_variables(self):
+        mod = self.pycore.get_string_module('def a_func():\n    a_var = 10\n')
+        a_func_scope = mod.get_scope().get_scopes()[0]
+        a_var = a_func_scope['a_var']
+        self.assertEquals((mod, 2), a_var.get_definition_location())
+
+    def test_get_pyname_definition_location_reassigning(self):
+        mod = self.pycore.get_string_module('a_var = 20\na_var=30\n')
+        a_var = mod['a_var']
+        self.assertEquals((mod, 1), a_var.get_definition_location())
+
+    def test_get_pyname_definition_location_importes(self):
+        module = testutils.create_module(self.project, 'mod')
+        mod = self.pycore.get_string_module('import mod\n')
+        imported_module = self.pycore.get_module('mod')
+        module_pyname = mod['mod']
+        self.assertEquals((imported_module, 1),
+                          module_pyname.get_definition_location())
+
+    def test_get_pyname_definition_location_imports(self):
+        module_resource = testutils.create_module(self.project, 'mod')
+        module_resource.write('\ndef a_func():\n    pass\n')
+        imported_module = self.pycore.get_module('mod')
+        mod = self.pycore.get_string_module('from mod import a_func\n')
+        a_func = mod['a_func']
+        self.assertEquals((imported_module, 2), a_func.get_definition_location())
+
+    def test_get_pyname_definition_location_parameters(self):
+        code = 'def a_func(param1, param2):\n    a_var = param\n'
+        mod = self.pycore.get_string_module(code)
+        a_func_scope = mod.get_scope().get_scopes()[0]
+        param1 = a_func_scope['param1']
+        self.assertEquals((mod, 1), param1.get_definition_location())
+        param2 = a_func_scope['param2']
+        self.assertEquals((mod, 1), param2.get_definition_location())
+
+    def test_module_get_resource(self):
+        module_resource = testutils.create_module(self.project, 'mod')
+        module = self.pycore.get_module('mod')
+        self.assertEquals(module_resource, module.get_resource())
+        string_module = self.pycore.get_string_module('from mod import a_func\n')
+        self.assertEquals(None, string_module.get_resource())
+
+    def test_get_pyname_definition_location_class2(self):
+        code = 'class AClass(object):\n' \
+               '    def __init__(self):\n' \
+               '        self.an_attr = 10\n'
+        mod = self.pycore.get_string_module(code)
+        a_class = mod['AClass'].get_object()
+        an_attr = a_class['an_attr']
+        self.assertEquals((mod, 3), an_attr.get_definition_location())
+
+    def test_import_not_found_module_get_definition_location(self):
+        mod = self.pycore.get_string_module('import doesnotexist\n')
+        does_not_exist = mod['doesnotexist']
+        self.assertEquals((None, None), does_not_exist.get_definition_location())
+
+    def test_from_not_found_module_get_definition_location(self):
+        mod = self.pycore.get_string_module('from doesnotexist import Sample\n')
+        sample = mod['Sample']
+        self.assertEquals((None, None), sample.get_definition_location())
+
+    def test_from_package_import_module_get_definition_location(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        testutils.create_module(self.project, 'mod', pkg)
+        pkg_mod = self.pycore.get_module('pkg.mod')
+        mod = self.pycore.get_string_module('from pkg import mod\n')
+        imported_mod = mod['mod']
+        self.assertEquals((pkg_mod, 1),
+                          imported_mod.get_definition_location())
+
+    def test_get_module_for_defined_pyobjects(self):
+        mod = self.pycore.get_string_module('class AClass(object):\n    pass\n')
+        a_class = mod['AClass'].get_object()
+        self.assertEquals(mod, a_class.get_module())
+
+    def test_get_definition_location_for_packages(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        init_module = self.pycore.get_module('pkg.__init__')
+        mod = self.pycore.get_string_module('import pkg\n')
+        pkg_pyname = mod['pkg']
+        self.assertEquals((init_module, 1), pkg_pyname.get_definition_location())
+
+    def test_get_definition_location_for_filtered_packages(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        testutils.create_module(self.project, 'mod', pkg)
+        init_module = self.pycore.get_module('pkg.__init__')
+        mod = self.pycore.get_string_module('import pkg.mod')
+        pkg_pyname = mod['pkg']
+        self.assertEquals((init_module, 1), pkg_pyname.get_definition_location())
+
+    def test_out_of_project_modules(self):
+        scope = self.pycore.get_string_scope('import rope.base.project as project\n')
+        imported_module = scope['project'].get_object()
+        self.assertTrue('Project' in imported_module)
+
+    def test_file_encoding_reading(self):
+        contents = u'# -*- coding: utf-8 -*-\n#\N{LATIN SMALL LETTER I WITH DIAERESIS}\n'
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write(contents)
+        self.pycore.get_module('mod')
+
+    def test_global_keyword(self):
+        contents = 'a_var = 1\ndef a_func():\n    global a_var\n'
+        mod = self.pycore.get_string_module(contents)
+        global_var = mod['a_var']
+        func_scope = mod['a_func'].get_object().get_scope()
+        local_var = func_scope['a_var']
+        self.assertEquals(global_var, local_var)
+
+    def test_not_leaking_for_vars_inside_parent_scope(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C(object):\n' \
+               '    def f(self):\n' \
+               '        for my_var1, my_var2 in []:\n' \
+               '            pass\n'
+        mod.write(code)
+        pymod = self.pycore.resource_to_pyobject(mod)
+        c_class = pymod['C'].get_object()
+        self.assertFalse('my_var1' in c_class)
+        self.assertFalse('my_var2' in c_class)
+
+    def test_not_leaking_for_vars_inside_parent_scope2(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C(object):\n' \
+               '    def f(self):\n' \
+               '        for my_var in []:\n' \
+               '            pass\n'
+        mod.write(code)
+        pymod = self.pycore.resource_to_pyobject(mod)
+        c_class = pymod['C'].get_object()
+        self.assertFalse('my_var' in c_class)
+
+    def test_variables_defined_in_excepts(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'try:\n' \
+               '    myvar1 = 1\n' \
+               'except:\n' \
+               '    myvar2 = 1\n' \
+               'finally:\n' \
+               '    myvar3 = 1\n'
+        mod.write(code)
+        pymod = self.pycore.resource_to_pyobject(mod)
+        self.assertTrue('myvar1' in pymod)
+        self.assertTrue('myvar2' in pymod)
+        self.assertTrue('myvar3' in pymod)
+
+    def test_not_leaking_tuple_assigned_names_inside_parent_scope(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C(object):\n' \
+               '    def f(self):\n' \
+               '        var1, var2 = range(2)\n'
+        mod.write(code)
+        pymod = self.pycore.resource_to_pyobject(mod)
+        c_class = pymod['C'].get_object()
+        self.assertFalse('var1' in c_class)
+
+    @testutils.run_only_for_25
+    def test_with_statement_variables(self):
+        code = 'import threading\nwith threading.lock() as var:    pass\n'
+        if sys.version_info < (2, 6, 0):
+            code = 'from __future__ import with_statement\n' + code
+        pymod = self.pycore.get_string_module(code)
+        self.assertTrue('var' in pymod)
+
+    @testutils.run_only_for_25
+    def test_with_statement_variables_and_tuple_assignment(self):
+        code = 'class A(object):\n' \
+               '    def __enter__(self):' \
+               '        return (1, 2)\n' \
+               '    def __exit__(self, type, value, tb):\n' \
+               '        pass\n'\
+               'with A() as (a, b):\n' \
+               '    pass\n'
+        if sys.version_info < (2, 6, 0):
+            code = 'from __future__ import with_statement\n' + code
+        pymod = self.pycore.get_string_module(code)
+        self.assertTrue('a' in pymod)
+        self.assertTrue('b' in pymod)
+
+    @testutils.run_only_for_25
+    def test_with_statement_variable_type(self):
+        code = 'class A(object):\n' \
+               '    def __enter__(self):\n' \
+               '        return self\n'\
+               '    def __exit__(self, type, value, tb):\n' \
+               '        pass\n' \
+               'with A() as var:\n' \
+               '    pass\n'
+        if sys.version_info < (2, 6, 0):
+            code = 'from __future__ import with_statement\n' + code
+        pymod = self.pycore.get_string_module(code)
+        a_class = pymod['A'].get_object()
+        var = pymod['var'].get_object()
+        self.assertEquals(a_class, var.get_type())
+
+    @testutils.run_only_for_25
+    def test_with_statement_with_no_vars(self):
+        code = 'with open("file"):    pass\n'
+        if sys.version_info < (2, 6, 0):
+            code = 'from __future__ import with_statement\n' + code
+        pymod = self.pycore.get_string_module(code)
+        pymod.get_attributes()
+
+    def test_check_for_else_block(self):
+        code = 'for i in range(10):\n' \
+               '    pass\n' \
+               'else:\n' \
+               '    myvar = 1\n'
+        mod = self.pycore.get_string_module(code)
+        a_var = mod['myvar']
+        self.assertEquals((mod, 4), a_var.get_definition_location())
+
+    def test_check_names_defined_in_whiles(self):
+        mod = self.pycore.get_string_module('while False:\n    myvar = 1\n')
+        a_var = mod['myvar']
+        self.assertEquals((mod, 2), a_var.get_definition_location())
+
+    def test_get_definition_location_in_tuple_assnames(self):
+        mod = self.pycore.get_string_module(
+            'def f(x):\n    x.z, a = range(2)\n')
+        x = mod['f'].get_object().get_scope()['x']
+        a = mod['f'].get_object().get_scope()['a']
+        self.assertEquals((mod, 1), x.get_definition_location())
+        self.assertEquals((mod, 2), a.get_definition_location())
+
+    @testutils.assert_raises(exceptions.ModuleSyntaxError)
+    def test_syntax_errors_in_code(self):
+        mod = self.pycore.get_string_module('xyx print\n')
+
+    def test_holding_error_location_information(self):
+        try:
+            mod = self.pycore.get_string_module('xyx print\n')
+        except exceptions.ModuleSyntaxError, e:
+            self.assertEquals(1, e.lineno)
+
+    def test_no_exceptions_on_module_encoding_problems(self):
+        mod = testutils.create_module(self.project, 'mod')
+        contents = '\nsdsdsd\n\xa9\n'
+        file = open(mod.real_path, 'wb')
+        file.write(contents)
+        file.close()
+        mod.read()
+
+    @testutils.assert_raises(exceptions.ModuleSyntaxError)
+    def test_syntax_errors_when_cannot_decode_file2(self):
+        mod = testutils.create_module(self.project, 'mod')
+        contents = '\n\xa9\n'
+        file = open(mod.real_path, 'wb')
+        file.write(contents)
+        file.close()
+        self.pycore.resource_to_pyobject(mod)
+
+    @testutils.assert_raises(exceptions.ModuleSyntaxError)
+    def test_syntax_errors_when_null_bytes(self):
+        mod = testutils.create_module(self.project, 'mod')
+        contents = '\n\x00\n'
+        file = open(mod.real_path, 'wb')
+        file.write(contents)
+        file.close()
+        self.pycore.resource_to_pyobject(mod)
+
+    @testutils.assert_raises(exceptions.ModuleSyntaxError)
+    def test_syntax_errors_when_bad_strs(self):
+        mod = testutils.create_module(self.project, 'mod')
+        contents = '\n"\\x0"\n'
+        file = open(mod.real_path, 'wb')
+        file.write(contents)
+        file.close()
+        self.pycore.resource_to_pyobject(mod)
+
+    def test_not_reaching_maximum_recursions_with_from_star_imports(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('from mod2 import *\n')
+        mod2.write('from mod1 import *\n')
+        pymod1 = self.pycore.resource_to_pyobject(mod1)
+        pymod1.get_attributes()
+
+    def test_not_reaching_maximum_recursions_when_importing_variables(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('from mod2 import myvar\n')
+        mod2.write('from mod1 import myvar\n')
+        pymod1 = self.pycore.resource_to_pyobject(mod1)
+        pymod1['myvar'].get_object()
+
+    def test_not_reaching_maximum_recursions_when_importing_variables2(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('from mod1 import myvar\n')
+        pymod1 = self.pycore.resource_to_pyobject(mod1)
+        pymod1['myvar'].get_object()
+
+    def test_pyobject_equality_should_compare_types(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('var1 = ""\nvar2 = ""\n')
+        pymod1 = self.pycore.resource_to_pyobject(mod1)
+        self.assertEquals(pymod1['var1'].get_object(),
+                          pymod1['var2'].get_object())
+
+
+class PyCoreInProjectsTest(unittest.TestCase):
+
+    def setUp(self):
+        super(self.__class__, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+        samplemod = testutils.create_module(self.project, 'samplemod')
+        code = 'class SampleClass(object):\n' \
+               '    def sample_method():\n' \
+               '        pass\n\n' \
+               'def sample_func():\n' \
+               '    pass\n' \
+               'sample_var = 10\n\n' \
+               'def _underlined_func():\n' \
+               '    pass\n\n'
+        samplemod.write(code)
+        package = testutils.create_package(self.project, 'package')
+        nestedmod = testutils.create_module(self.project, 'nestedmod', package)
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(self.__class__, self).tearDown()
+
+    def test_simple_import(self):
+        mod = self.pycore.get_string_module('import samplemod\n')
+        samplemod = mod['samplemod'].get_object()
+        self.assertEquals(get_base_type('Module'), samplemod.get_type())
+
+    def test_from_import_class(self):
+        mod = self.pycore.get_string_module('from samplemod import SampleClass\n')
+        result = mod['SampleClass'].get_object()
+        self.assertEquals(get_base_type('Type'), result.get_type())
+        self.assertTrue('sample_func' not in mod.get_attributes())
+
+    def test_from_import_star(self):
+        mod = self.pycore.get_string_module('from samplemod import *\n')
+        self.assertEquals(get_base_type('Type'),
+                          mod['SampleClass'].get_object().get_type())
+        self.assertEquals(get_base_type('Function'),
+                          mod['sample_func'].get_object().get_type())
+        self.assertTrue(mod['sample_var'] is not None)
+
+    def test_from_import_star_overwriting(self):
+        code = 'from samplemod import *\n' \
+               'class SampleClass(object):\n    pass\n'
+        mod = self.pycore.get_string_module(code)
+        samplemod = self.pycore.get_module('samplemod')
+        sample_class = samplemod['SampleClass'].get_object()
+        self.assertNotEquals(sample_class,
+                             mod.get_attributes()['SampleClass'].get_object())
+
+    def test_from_import_star_not_imporing_underlined(self):
+        mod = self.pycore.get_string_module('from samplemod import *')
+        self.assertTrue('_underlined_func' not in mod.get_attributes())
+
+    def test_from_import_star_imports_in_functions(self):
+        mod = self.pycore.get_string_module('def f():\n    from os import *\n')
+        mod['f'].get_object().get_scope().get_names()
+
+    def test_from_package_import_mod(self):
+        mod = self.pycore.get_string_module('from package import nestedmod\n')
+        self.assertEquals(get_base_type('Module'),
+                          mod['nestedmod'].get_object().get_type())
+
+    # XXX: Deciding to import everything on import start from packages
+    def xxx_test_from_package_import_star(self):
+        mod = self.pycore.get_string_module('from package import *\n')
+        self.assertTrue('nestedmod' not in mod.get_attributes())
+
+    def test_unknown_when_module_cannot_be_found(self):
+        mod = self.pycore.get_string_module('from doesnotexist import nestedmod\n')
+        self.assertTrue('nestedmod' in mod)
+
+    def test_from_import_function(self):
+        code = 'def f():\n    from samplemod import SampleClass\n'
+        scope = self.pycore.get_string_scope(code)
+        self.assertEquals(get_base_type('Type'),
+                          scope.get_scopes()[0]['SampleClass'].
+                          get_object().get_type())
+
+    def test_circular_imports(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('import mod2\n')
+        mod2.write('import mod1\n')
+        module1 = self.pycore.get_module('mod1')
+
+    def test_circular_imports2(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('from mod2 import Sample2\nclass Sample1(object):\n    pass\n')
+        mod2.write('from mod1 import Sample1\nclass Sample2(object):\n    pass\n')
+        module1 = self.pycore.get_module('mod1').get_attributes()
+
+    def test_multi_dot_imports(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        pkg_mod = testutils.create_module(self.project, 'mod', pkg)
+        pkg_mod.write('def sample_func():\n    pass\n')
+        mod = self.pycore.get_string_module('import pkg.mod\n')
+        self.assertTrue('pkg' in mod)
+        self.assertTrue('sample_func' in mod['pkg'].get_object()['mod'].
+                                get_object())
+
+    def test_multi_dot_imports2(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1 = testutils.create_module(self.project, 'mod1', pkg)
+        mod2 = testutils.create_module(self.project, 'mod2', pkg)
+        mod = self.pycore.get_string_module('import pkg.mod1\nimport pkg.mod2\n')
+        package = mod['pkg'].get_object()
+        self.assertEquals(2, len(package.get_attributes()))
+        self.assertTrue('mod1' in package and
+                        'mod2' in package)
+
+    def test_multi_dot_imports3(self):
+        pkg1 = testutils.create_package(self.project, 'pkg1')
+        pkg2 = testutils.create_package(self.project, 'pkg2', pkg1)
+        mod1 = testutils.create_module(self.project, 'mod1', pkg2)
+        mod2 = testutils.create_module(self.project, 'mod2', pkg2)
+        code = 'import pkg1.pkg2.mod1\nimport pkg1.pkg2.mod2\n'
+        mod = self.pycore.get_string_module(code)
+        package1 = mod['pkg1'].get_object()
+        package2 = package1['pkg2'].get_object()
+        self.assertEquals(2, len(package2.get_attributes()))
+        self.assertTrue('mod1' in package2 and 'mod2' in package2)
+
+    def test_multi_dot_imports_as(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1 = testutils.create_module(self.project, 'mod1', pkg)
+        mod1.write('def f():\n    pass\n')
+        mod = self.pycore.get_string_module('import pkg.mod1 as mod1\n')
+        module = mod['mod1'].get_object()
+        self.assertTrue('f' in module)
+
+    # TODO: not showing unimported names as attributes of packages
+    def xxx_test_from_package_import_package(self):
+        pkg1 = testutils.create_package(self.project, 'pkg1')
+        pkg2 = testutils.create_package(self.project, 'pkg2', pkg1)
+        module = testutils.create_module(self.project, 'mod', pkg2)
+        mod = self.pycore.get_string_module('from pkg1 import pkg2\n')
+        package = mod['pkg2']
+        self.assertEquals(0, len(package.get_attributes()))
+
+    def test_invalidating_cache_after_resource_change(self):
+        module = testutils.create_module(self.project, 'mod')
+        module.write('import sys\n')
+        mod1 = self.pycore.get_module('mod')
+        self.assertTrue('var' not in mod1.get_attributes())
+        module.write('var = 10\n')
+        mod2 = self.pycore.get_module('mod')
+        self.assertTrue('var' in mod2)
+
+    def test_invalidating_cache_after_resource_change_for_init_dot_pys(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod = testutils.create_module(self.project, 'mod')
+        init_dot_py = pkg.get_child('__init__.py')
+        init_dot_py.write('a_var = 10\n')
+        mod.write('import pkg\n')
+        pymod = self.pycore.get_module('mod')
+        self.assertTrue('a_var' in pymod['pkg'].get_object())
+        init_dot_py.write('new_var = 10\n')
+        self.assertTrue('a_var' not in pymod['pkg'].get_object().get_attributes())
+
+    def test_invalidating_cache_after_resource_change_for_nested_init_dot_pys(self):
+        pkg1 = testutils.create_package(self.project, 'pkg1')
+        pkg2 = testutils.create_package(self.project, 'pkg2', pkg1)
+        mod = testutils.create_module(self.project, 'mod')
+        init_dot_py = pkg2.get_child('__init__.py')
+        init_dot_py.write('a_var = 10\n')
+        mod.write('import pkg1\n')
+        pymod = self.pycore.get_module('mod')
+        self.assertTrue('a_var' in pymod['pkg1'].get_object()['pkg2'].get_object())
+        init_dot_py.write('new_var = 10\n')
+        self.assertTrue('a_var' not in pymod['pkg1'].get_object()['pkg2'].get_object())
+
+    def test_from_import_nonexistent_module(self):
+        code = 'from doesnotexistmod import DoesNotExistClass\n'
+        mod = self.pycore.get_string_module(code)
+        self.assertTrue('DoesNotExistClass' in mod)
+        self.assertEquals(get_base_type('Unknown'),
+                          mod['DoesNotExistClass'].
+                          get_object().get_type())
+
+    def test_from_import_nonexistent_name(self):
+        code = 'from samplemod import DoesNotExistClass\n'
+        mod = self.pycore.get_string_module(code)
+        self.assertTrue('DoesNotExistClass' in mod)
+        self.assertEquals(get_base_type('Unknown'),
+                          mod['DoesNotExistClass'].
+                          get_object().get_type())
+
+    def test_not_considering_imported_names_as_sub_scopes(self):
+        code = 'from samplemod import SampleClass\n'
+        scope = self.pycore.get_string_scope(code)
+        self.assertEquals(0, len(scope.get_scopes()))
+
+    def test_not_considering_imported_modules_as_sub_scopes(self):
+        scope = self.pycore.get_string_scope('import samplemod\n')
+        self.assertEquals(0, len(scope.get_scopes()))
+
+    def test_inheriting_dotted_base_class(self):
+        code = 'import samplemod\n' \
+               'class Derived(samplemod.SampleClass):\n' \
+               '    pass\n'
+        mod = self.pycore.get_string_module(code)
+        derived = mod['Derived'].get_object()
+        self.assertTrue('sample_method' in derived)
+
+    def test_self_in_methods(self):
+        code = 'class Sample(object):\n' \
+               '    def func(self):\n' \
+               '        pass\n'
+        scope = self.pycore.get_string_scope(code)
+        sample_class = scope['Sample'].get_object()
+        func_scope = scope.get_scopes()[0].get_scopes()[0]
+        self.assertEquals(sample_class,
+                          func_scope['self'].get_object().get_type())
+        self.assertTrue('func' in func_scope['self'].
+                                get_object())
+
+    def test_none_assignments_in_classes(self):
+        code = 'class C(object):\n' \
+               '    var = ""\n' \
+               '    def f(self):\n' \
+               '        self.var += "".join([])\n'
+        scope = self.pycore.get_string_scope(
+            code)
+        c_class = scope['C'].get_object()
+        self.assertTrue('var' in c_class)
+
+    def test_self_in_methods_with_decorators(self):
+        code = 'class Sample(object):\n' \
+               '    @staticmethod\n' \
+               '    def func(self):\n' \
+               '        pass\n'
+        scope = self.pycore.get_string_scope(code)
+        sample_class = scope['Sample'].get_object()
+        func_scope = scope.get_scopes()[0].get_scopes()[0]
+        self.assertNotEquals(sample_class,
+                             func_scope['self'].get_object().get_type())
+
+    def test_location_of_imports_when_importing(self):
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('from samplemod import SampleClass\n')
+        scope = self.pycore.get_string_scope('from mod import SampleClass\n')
+        sample_class = scope['SampleClass']
+        samplemod = self.pycore.get_module('samplemod')
+        self.assertEquals((samplemod, 1), sample_class.get_definition_location())
+
+    def test_nested_modules(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod = testutils.create_module(self.project, 'mod', pkg)
+        imported_module = self.pycore.get_module('pkg.mod')
+        scope = self.pycore.get_string_scope('import pkg.mod\n')
+        mod_pyobject = scope['pkg'].get_object()['mod']
+        self.assertEquals((imported_module, 1),
+                          mod_pyobject.get_definition_location())
+
+    def test_reading_init_dot_py(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        init_dot_py = pkg.get_child('__init__.py')
+        init_dot_py.write('a_var = 1\n')
+        pkg_object = self.pycore.get_module('pkg')
+        self.assertTrue('a_var' in pkg_object)
+
+    def test_relative_imports(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1 = testutils.create_module(self.project, 'mod1', pkg)
+        mod2 = testutils.create_module(self.project, 'mod2', pkg)
+        mod2.write('import mod1\n')
+        mod1_object = self.pycore.resource_to_pyobject(mod1)
+        mod2_object = self.pycore.resource_to_pyobject(mod2)
+        self.assertEquals(mod1_object, mod2_object.get_attributes()['mod1'].get_object())
+
+    def test_relative_froms(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1 = testutils.create_module(self.project, 'mod1', pkg)
+        mod2 = testutils.create_module(self.project, 'mod2', pkg)
+        mod1.write('def a_func():\n    pass\n')
+        mod2.write('from mod1 import a_func\n')
+        mod1_object = self.pycore.resource_to_pyobject(mod1)
+        mod2_object = self.pycore.resource_to_pyobject(mod2)
+        self.assertEquals(mod1_object['a_func'].get_object(),
+                          mod2_object['a_func'].get_object())
+
+    def test_relative_imports_for_string_modules(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1 = testutils.create_module(self.project, 'mod1', pkg)
+        mod2 = testutils.create_module(self.project, 'mod2', pkg)
+        mod2.write('import mod1\n')
+        mod1_object = self.pycore.resource_to_pyobject(mod1)
+        mod2_object = self.pycore.get_string_module(mod2.read(), mod2)
+        self.assertEquals(mod1_object, mod2_object['mod1'].get_object())
+
+    def test_relative_imports_for_string_scopes(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1 = testutils.create_module(self.project, 'mod1', pkg)
+        mod2 = testutils.create_module(self.project, 'mod2', pkg)
+        mod2.write('import mod1\n')
+        mod1_object = self.pycore.resource_to_pyobject(mod1)
+        mod2_scope = self.pycore.get_string_scope(mod2.read(), mod2)
+        self.assertEquals(mod1_object, mod2_scope['mod1'].get_object())
+
+    @testutils.run_only_for_25
+    def test_new_style_relative_imports(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1 = testutils.create_module(self.project, 'mod1', pkg)
+        mod2 = testutils.create_module(self.project, 'mod2', pkg)
+        mod2.write('from . import mod1\n')
+        mod1_object = self.pycore.resource_to_pyobject(mod1)
+        mod2_object = self.pycore.resource_to_pyobject(mod2)
+        self.assertEquals(mod1_object, mod2_object['mod1'].get_object())
+
+    @testutils.run_only_for_25
+    def test_new_style_relative_imports2(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2', pkg)
+        mod1.write('def a_func():\n    pass\n')
+        mod2.write('from ..mod1 import a_func\n')
+        mod1_object = self.pycore.resource_to_pyobject(mod1)
+        mod2_object = self.pycore.resource_to_pyobject(mod2)
+        self.assertEquals(mod1_object['a_func'].get_object(),
+                          mod2_object['a_func'].get_object())
+
+    def test_invalidating_cache_for_from_imports_after_resource_change(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod2.write('def a_func():\n    print(1)\n')
+        mod1.write('from mod2 import a_func\na_func()\n')
+
+        pymod1 = self.pycore.get_module('mod1')
+        pymod2 = self.pycore.get_module('mod2')
+        self.assertEquals(pymod1['a_func'].get_object(),
+                          pymod2['a_func'].get_object())
+        mod2.write(mod2.read() + '\n')
+        pymod2 = self.pycore.get_module('mod2')
+        self.assertEquals(pymod1['a_func'].get_object(),
+                          pymod2['a_func'].get_object())
+
+    def test_invalidating_superclasses_after_change(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('class A(object):\n    def func1(self):\n        pass\n')
+        mod2.write('import mod1\nclass B(mod1.A):\n    pass\n')
+
+        b_class = self.pycore.get_module('mod2')['B'].get_object()
+        self.assertTrue('func1' in b_class)
+
+        mod1.write('class A(object):\n    def func2(self):\n        pass\n')
+        self.assertTrue('func2' in b_class)
+
+    def test_caching_pymodule_with_syntax_errors(self):
+        self.project.prefs['ignore_syntax_errors'] = True
+        self.project.prefs['automatic_soa'] = True
+        self.project.pycore._init_automatic_soa()
+        source = 'import sys\nab cd'
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write(source)
+        from rope.contrib import fixsyntax
+        fixer = fixsyntax.FixSyntax(self.project.pycore, source, mod, 10)
+        pymodule = fixer.get_pymodule()
+        self.assertTrue(pymodule.source_code.startswith('import sys\npass\n'))
+
+
+class TextChangeDetectorTest(unittest.TestCase):
+
+    def test_trivial_case(self):
+        detector = _TextChangeDetector('\n', '\n')
+        self.assertFalse(detector.is_changed(1, 1))
+
+    def test_one_line_change(self):
+        detector = _TextChangeDetector('1\n2\n', '1\n3\n')
+        self.assertFalse(detector.is_changed(1, 1))
+        self.assertTrue(detector.is_changed(2, 2))
+
+    def test_line_expansion(self):
+        detector = _TextChangeDetector('1\n2\n', '1\n3\n4\n2\n')
+        self.assertFalse(detector.is_changed(1, 1))
+        self.assertFalse(detector.is_changed(2, 2))
+
+    def test_line_removals(self):
+        detector = _TextChangeDetector('1\n3\n4\n2\n', '1\n2\n')
+        self.assertFalse(detector.is_changed(1, 1))
+        self.assertTrue(detector.is_changed(2, 3))
+        self.assertFalse(detector.is_changed(4, 4))
+
+    def test_multi_line_checks(self):
+        detector = _TextChangeDetector('1\n2\n', '1\n3\n')
+        self.assertTrue(detector.is_changed(1, 2))
+
+    def test_consume_change(self):
+        detector = _TextChangeDetector('1\n2\n', '1\n3\n')
+        self.assertTrue(detector.is_changed(1, 2))
+        self.assertTrue(detector.consume_changes(1, 2))
+        self.assertFalse(detector.is_changed(1, 2))
+
+
+class PyCoreProjectConfigsTest(unittest.TestCase):
+
+    def setUp(self):
+        super(PyCoreProjectConfigsTest, self).setUp()
+        self.project = None
+
+    def tearDown(self):
+        if self.project:
+            testutils.remove_project(self.project)
+        super(PyCoreProjectConfigsTest, self).tearDown()
+
+    def test_python_files_config(self):
+        self.project = testutils.sample_project(python_files=['myscript'])
+        myscript = self.project.root.create_file('myscript')
+        self.assertTrue(self.project.pycore.is_python_file(myscript))
+
+    def test_ignore_bad_imports(self):
+        self.project = testutils.sample_project(ignore_bad_imports=True)
+        pymod = self.project.pycore.get_string_module(
+            'import some_nonexistent_module\n')
+        self.assertFalse('some_nonexistent_module' in pymod)
+
+    def test_ignore_bad_imports_for_froms(self):
+        self.project = testutils.sample_project(ignore_bad_imports=True)
+        pymod = self.project.pycore.get_string_module(
+            'from some_nonexistent_module import var\n')
+        self.assertFalse('var' in pymod)
+
+    @testutils.assert_raises(exceptions.ModuleSyntaxError)
+    def test_reporting_syntax_errors_with_force_errors(self):
+        self.project = testutils.sample_project(ignore_syntax_errors=True)
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('syntax error ...\n')
+        self.project.pycore.resource_to_pyobject(mod, force_errors=True)
+
+    @testutils.assert_raises(exceptions.ModuleSyntaxError)
+    def test_reporting_syntax_errors_in_strings_with_force_errors(self):
+        self.project = testutils.sample_project(ignore_syntax_errors=True)
+        self.project.pycore.get_string_module('syntax error ...',
+                                              force_errors=True)
+
+    def test_not_raising_errors_for_strings_with_ignore_errors(self):
+        self.project = testutils.sample_project(ignore_syntax_errors=True)
+        self.project.pycore.get_string_module('syntax error ...')
+
+    @testutils.assert_raises(exceptions.ModuleSyntaxError)
+    def test_reporting_syntax_errors_with_force_errors_for_packages(self):
+        self.project = testutils.sample_project(ignore_syntax_errors=True)
+        pkg = testutils.create_package(self.project, 'pkg')
+        pkg.get_child('__init__.py').write('syntax error ...\n')
+        self.project.pycore.resource_to_pyobject(pkg, force_errors=True)
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(PyCoreTest))
+    result.addTests(unittest.makeSuite(PyCoreInProjectsTest))
+    result.addTests(unittest.makeSuite(TextChangeDetectorTest))
+    result.addTests(unittest.makeSuite(PyCoreProjectConfigsTest))
+    return result
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/pyscopestest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,235 @@
+import unittest
+
+from rope.base.pyobjects import get_base_type
+from ropetest import testutils
+
+
+class PyCoreScopesTest(unittest.TestCase):
+
+    def setUp(self):
+        super(PyCoreScopesTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(PyCoreScopesTest, self).tearDown()
+
+    def test_simple_scope(self):
+        scope = self.pycore.get_string_scope('def sample_func():\n    pass\n')
+        sample_func = scope['sample_func'].get_object()
+        self.assertEquals(get_base_type('Function'), sample_func.get_type())
+
+    def test_simple_function_scope(self):
+        scope = self.pycore.get_string_scope(
+            'def sample_func():\n    a = 10\n')
+        self.assertEquals(1, len(scope.get_scopes()))
+        sample_func_scope = scope.get_scopes()[0]
+        self.assertEquals(1, len(sample_func_scope.get_names()))
+        self.assertEquals(0, len(sample_func_scope.get_scopes()))
+
+    def test_classes_inside_function_scopes(self):
+        scope = self.pycore.get_string_scope(
+            'def sample_func():\n'
+            '    class SampleClass(object):\n        pass\n')
+        self.assertEquals(1, len(scope.get_scopes()))
+        sample_func_scope = scope.get_scopes()[0]
+        self.assertEquals(get_base_type('Type'),
+                          scope.get_scopes()[0]['SampleClass'].get_object().get_type())
+
+    def test_simple_class_scope(self):
+        scope = self.pycore.get_string_scope(
+            'class SampleClass(object):\n'
+            '    def f(self):\n        var = 10\n')
+        self.assertEquals(1, len(scope.get_scopes()))
+        sample_class_scope = scope.get_scopes()[0]
+        self.assertTrue('f' in sample_class_scope)
+        self.assertEquals(1, len(sample_class_scope.get_scopes()))
+        f_in_class = sample_class_scope.get_scopes()[0]
+        self.assertTrue('var' in f_in_class)
+
+    def test_get_lineno(self):
+        scope = self.pycore.get_string_scope(
+            '\ndef sample_func():\n    a = 10\n')
+        self.assertEquals(1, len(scope.get_scopes()))
+        sample_func_scope = scope.get_scopes()[0]
+        self.assertEquals(1, scope.get_start())
+        self.assertEquals(2, sample_func_scope.get_start())
+
+    def test_scope_kind(self):
+        scope = self.pycore.get_string_scope(
+            'class SampleClass(object):\n    pass\n'
+            'def sample_func():\n    pass\n')
+        sample_class_scope = scope.get_scopes()[0]
+        sample_func_scope = scope.get_scopes()[1]
+        self.assertEquals('Module', scope.get_kind())
+        self.assertEquals('Class', sample_class_scope.get_kind())
+        self.assertEquals('Function', sample_func_scope.get_kind())
+
+    def test_function_parameters_in_scope_names(self):
+        scope = self.pycore.get_string_scope(
+            'def sample_func(param):\n    a = 10\n')
+        sample_func_scope = scope.get_scopes()[0]
+        self.assertTrue('param' in sample_func_scope)
+
+    def test_get_names_contains_only_names_defined_in_a_scope(self):
+        scope = self.pycore.get_string_scope(
+            'var1 = 10\ndef sample_func(param):\n    var2 = 20\n')
+        sample_func_scope = scope.get_scopes()[0]
+        self.assertTrue('var1' not in sample_func_scope)
+
+    def test_scope_lookup(self):
+        scope = self.pycore.get_string_scope(
+            'var1 = 10\ndef sample_func(param):\n    var2 = 20\n')
+        self.assertTrue(scope.lookup('var2') is None)
+        self.assertEquals(get_base_type('Function'),
+                          scope.lookup('sample_func').get_object().get_type())
+        sample_func_scope = scope.get_scopes()[0]
+        self.assertTrue(sample_func_scope.lookup('var1') is not None)
+
+    def test_function_scopes(self):
+        scope = self.pycore.get_string_scope('def func():\n    var = 10\n')
+        func_scope = scope.get_scopes()[0]
+        self.assertTrue('var' in func_scope)
+
+    def test_function_scopes_classes(self):
+        scope = self.pycore.get_string_scope(
+            'def func():\n    class Sample(object):\n        pass\n')
+        func_scope = scope.get_scopes()[0]
+        self.assertTrue('Sample' in func_scope)
+
+    def test_function_getting_scope(self):
+        mod = self.pycore.get_string_module('def func():    var = 10\n')
+        func_scope = mod['func'].get_object().get_scope()
+        self.assertTrue('var' in func_scope)
+
+    def test_scopes_in_function_scopes(self):
+        scope = self.pycore.get_string_scope(
+            'def func():\n    def inner():\n        var = 10\n')
+        func_scope = scope.get_scopes()[0]
+        inner_scope = func_scope.get_scopes()[0]
+        self.assertTrue('var' in inner_scope)
+
+    def test_for_variables_in_scopes(self):
+        scope = self.pycore.get_string_scope(
+            'for a_var in range(10):\n    pass\n')
+        self.assertTrue('a_var' in scope)
+
+    def test_assists_inside_fors(self):
+        scope = self.pycore.get_string_scope(
+            'for i in range(10):\n    a_var = i\n')
+        self.assertTrue('a_var' in scope)
+
+    def test_first_parameter_of_a_method(self):
+        code = 'class AClass(object):\n' \
+               '    def a_func(self, param):\n        pass\n'
+        a_class = self.pycore.get_string_module(code)['AClass']. get_object()
+        function_scope = a_class['a_func'].get_object().get_scope()
+        self.assertEquals(a_class, function_scope['self'].get_object().get_type())
+        self.assertNotEquals(a_class, function_scope['param'].
+                             get_object().get_type())
+
+    def test_first_parameter_of_static_methods(self):
+        code = 'class AClass(object):\n' \
+               '    @staticmethod\n    def a_func(param):\n        pass\n'
+        a_class = self.pycore.get_string_module(code)['AClass']. get_object()
+        function_scope = a_class['a_func'].\
+                         get_object().get_scope()
+        self.assertNotEquals(a_class, function_scope['param'].get_object().get_type())
+
+    def test_first_parameter_of_class_methods(self):
+        code = 'class AClass(object):\n' \
+            '    @classmethod\n    def a_func(cls):\n        pass\n'
+        a_class = self.pycore.get_string_module(code)['AClass']. get_object()
+        function_scope = a_class['a_func'].get_object().get_scope()
+        self.assertEquals(a_class, function_scope['cls'].get_object())
+
+    def test_first_parameter_with_self_as_name_and_unknown_decorator(self):
+        code = 'def my_decorator(func):\n    return func\n'\
+               'class AClass(object):\n' \
+               '    @my_decorator\n    def a_func(self):\n        pass\n'
+        a_class = self.pycore.get_string_module(code)['AClass']. get_object()
+        function_scope = a_class['a_func'].get_object().get_scope()
+        self.assertEquals(a_class, function_scope['self'].
+                          get_object().get_type())
+
+    def test_inside_class_scope_attribute_lookup(self):
+        scope = self.pycore.get_string_scope(
+            'class C(object):\n'
+            '    an_attr = 1\n'
+            '    def a_func(self):\n        pass')
+        self.assertEquals(1, len(scope.get_scopes()))
+        c_scope = scope.get_scopes()[0]
+        self.assertTrue('an_attr'in c_scope.get_names())
+        self.assertTrue(c_scope.lookup('an_attr') is not None)
+        f_in_c = c_scope.get_scopes()[0]
+        self.assertTrue(f_in_c.lookup('an_attr') is None)
+
+    def test_inside_class_scope_attribute_lookup2(self):
+        scope = self.pycore.get_string_scope(
+            'class C(object):\n'
+            '    def __init__(self):\n        self.an_attr = 1\n'
+            '    def a_func(self):\n        pass')
+        self.assertEquals(1, len(scope.get_scopes()))
+        c_scope = scope.get_scopes()[0]
+        f_in_c = c_scope.get_scopes()[0]
+        self.assertTrue(f_in_c.lookup('an_attr') is None)
+
+    def test_get_inner_scope_for_staticmethods(self):
+        scope = self.pycore.get_string_scope(
+            'class C(object):\n'
+            '    @staticmethod\n'
+            '    def a_func(self):\n        pass\n')
+        c_scope = scope.get_scopes()[0]
+        f_in_c = c_scope.get_scopes()[0]
+        self.assertEquals(f_in_c, scope.get_inner_scope_for_line(4))
+
+    def test_getting_overwritten_scopes(self):
+        scope = self.pycore.get_string_scope(
+            'def f():\n    pass\ndef f():\n    pass\n')
+        self.assertEquals(2, len(scope.get_scopes()))
+        f1_scope = scope.get_scopes()[0]
+        f2_scope = scope.get_scopes()[1]
+        self.assertNotEquals(f1_scope, f2_scope)
+
+    def test_assigning_builtin_names(self):
+        mod = self.pycore.get_string_module('range = 1\n')
+        range = mod.get_scope().lookup('range')
+        self.assertEquals((mod, 1), range.get_definition_location())
+
+    def test_get_inner_scope_and_logical_lines(self):
+        scope = self.pycore.get_string_scope(
+            'class C(object):\n'
+            '    def f():\n        s = """\n1\n2\n"""\n        a = 1\n')
+        c_scope = scope.get_scopes()[0]
+        f_in_c = c_scope.get_scopes()[0]
+        self.assertEquals(f_in_c, scope.get_inner_scope_for_line(7))
+
+    def test_getting_defined_names_for_classes(self):
+        scope = self.pycore.get_string_scope(
+            'class A(object):\n    def a(self):\n        pass\n'
+            'class B(A):\n    def b(self):\n        pass\n')
+        a_scope = scope['A'].get_object().get_scope()
+        b_scope = scope['B'].get_object().get_scope()
+        self.assertTrue('a' in b_scope.get_names())
+        self.assertTrue('b' in b_scope.get_names())
+        self.assertTrue('a' not in b_scope.get_defined_names())
+        self.assertTrue('b' in b_scope.get_defined_names())
+
+    def test_getting_defined_names_for_modules(self):
+        scope = self.pycore.get_string_scope(
+            'class A(object):\n    pass\n')
+        self.assertTrue('open' in scope.get_names())
+        self.assertTrue('A' in scope.get_names())
+        self.assertTrue('open' not in scope.get_defined_names())
+        self.assertTrue('A' in scope.get_defined_names())
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(PyCoreScopesTest))
+    return result
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/refactor/__init__.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,925 @@
+import unittest
+
+import rope.base.taskhandle
+import rope.refactor.introduce_parameter
+import ropetest.refactor.extracttest
+import ropetest.refactor.importutilstest
+import ropetest.refactor.inlinetest
+import ropetest.refactor.movetest
+import ropetest.refactor.multiprojecttest
+import ropetest.refactor.patchedasttest
+import ropetest.refactor.renametest
+import ropetest.refactor.restructuretest
+import ropetest.refactor.suitestest
+import ropetest.refactor.usefunctiontest
+from rope.base.exceptions import RefactoringError, InterruptedTaskError
+from rope.refactor.encapsulate_field import EncapsulateField
+from rope.refactor.introduce_factory import IntroduceFactory
+from rope.refactor.localtofield import LocalToField
+from rope.refactor.method_object import MethodObject
+from ropetest import testutils
+from ropetest.refactor import change_signature_test, similarfindertest
+
+
+class MethodObjectTest(unittest.TestCase):
+
+    def setUp(self):
+        super(MethodObjectTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+        self.mod = testutils.create_module(self.project, 'mod')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(MethodObjectTest, self).tearDown()
+
+    def test_empty_method(self):
+        code = 'def func():\n    pass\n'
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
+        self.assertEquals(
+            'class _New(object):\n\n    def __call__(self):\n        pass\n',
+            replacer.get_new_class('_New'))
+
+    def test_trivial_return(self):
+        code = 'def func():\n    return 1\n'
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
+        self.assertEquals(
+            'class _New(object):\n\n    def __call__(self):\n        return 1\n',
+            replacer.get_new_class('_New'))
+
+    def test_multi_line_header(self):
+        code = 'def func(\n    ):\n    return 1\n'
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
+        self.assertEquals(
+            'class _New(object):\n\n    def __call__(self):\n        return 1\n',
+            replacer.get_new_class('_New'))
+
+    def test_a_single_parameter(self):
+        code = 'def func(param):\n    return 1\n'
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
+        self.assertEquals(
+            'class _New(object):\n\n'
+            '    def __init__(self, param):\n        self.param = param\n\n'
+            '    def __call__(self):\n        return 1\n',
+            replacer.get_new_class('_New'))
+
+    def test_self_parameter(self):
+        code = 'def func(self):\n    return 1\n'
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
+        self.assertEquals(
+            'class _New(object):\n\n'
+            '    def __init__(self, host):\n        self.self = host\n\n'
+            '    def __call__(self):\n        return 1\n',
+            replacer.get_new_class('_New'))
+
+    def test_simple_using_passed_parameters(self):
+        code = 'def func(param):\n    return param\n'
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
+        self.assertEquals(
+            'class _New(object):\n\n'
+            '    def __init__(self, param):\n        self.param = param\n\n'
+            '    def __call__(self):\n        return self.param\n',
+            replacer.get_new_class('_New'))
+
+    def test_self_keywords_and_args_parameters(self):
+        code = 'def func(arg, *args, **kwds):\n' \
+               '    result = arg + args[0] + kwds[arg]\n' \
+               '    return result\n'
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
+        expected = 'class _New(object):\n\n' \
+                   '    def __init__(self, arg, args, kwds):\n' \
+                   '        self.arg = arg\n' \
+                   '        self.args = args\n' \
+                   '        self.kwds = kwds\n\n' \
+                   '    def __call__(self):\n' \
+                   '        result = self.arg + self.args[0] + self.kwds[self.arg]\n' \
+                   '        return result\n'
+        self.assertEquals(expected, replacer.get_new_class('_New'))
+
+    @testutils.assert_raises(RefactoringError)
+    def test_performing_on_not_a_function(self):
+        code = 'my_var = 10\n'
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('my_var'))
+
+    def test_changing_the_module(self):
+        code = 'def func():\n    return 1\n'
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
+        self.project.do(replacer.get_changes('_New'))
+        expected = 'def func():\n' \
+                   '    return _New()()\n\n\n' \
+                   'class _New(object):\n\n' \
+                   '    def __call__(self):\n' \
+                   '        return 1\n'
+        self.assertEquals(expected, self.mod.read())
+
+    def test_changing_the_module_and_class_methods(self):
+        code = 'class C(object):\n\n' \
+               '    def a_func(self):\n' \
+               '        return 1\n\n' \
+               '    def another_func(self):\n' \
+               '        pass\n'
+        self.mod.write(code)
+        replacer = MethodObject(self.project, self.mod, code.index('func'))
+        self.project.do(replacer.get_changes('_New'))
+        expected = 'class C(object):\n\n' \
+                   '    def a_func(self):\n' \
+                   '        return _New(self)()\n\n' \
+                   '    def another_func(self):\n' \
+                   '        pass\n\n\n' \
+                   'class _New(object):\n\n' \
+                   '    def __init__(self, host):\n' \
+                   '        self.self = host\n\n' \
+                   '    def __call__(self):\n' \
+                   '        return 1\n'
+        self.assertEquals(expected, self.mod.read())
+
+
+class IntroduceFactoryTest(unittest.TestCase):
+
+    def setUp(self):
+        super(IntroduceFactoryTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(IntroduceFactoryTest, self).tearDown()
+
+    def _introduce_factory(self, resource, offset, *args, **kwds):
+        factory_introducer = IntroduceFactory(self.project,
+                                              resource, offset)
+        changes = factory_introducer.get_changes(*args, **kwds)
+        self.project.do(changes)
+
+    def test_adding_the_method(self):
+        code = 'class AClass(object):\n    an_attr = 10\n'
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write(code)
+        expected = 'class AClass(object):\n' \
+                   '    an_attr = 10\n\n' \
+                   '    @staticmethod\n' \
+                   '    def create(*args, **kwds):\n' \
+                   '        return AClass(*args, **kwds)\n'
+        self._introduce_factory(mod, mod.read().index('AClass') + 1, 'create')
+        self.assertEquals(expected, mod.read())
+
+    def test_changing_occurances_in_the_main_module(self):
+        code = 'class AClass(object):\n' \
+               '    an_attr = 10\n' \
+               'a_var = AClass()'
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write(code)
+        expected = 'class AClass(object):\n' \
+                   '    an_attr = 10\n\n' \
+                   '    @staticmethod\n' \
+                   '    def create(*args, **kwds):\n' \
+                   '        return AClass(*args, **kwds)\n'\
+                   'a_var = AClass.create()'
+        self._introduce_factory(mod, mod.read().index('AClass') + 1, 'create')
+        self.assertEquals(expected, mod.read())
+
+    def test_changing_occurances_with_arguments(self):
+        code = 'class AClass(object):\n' \
+               '    def __init__(self, arg):\n' \
+               '        pass\n' \
+               'a_var = AClass(10)\n'
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write(code)
+        expected = 'class AClass(object):\n' \
+                   '    def __init__(self, arg):\n' \
+                   '        pass\n\n' \
+                   '    @staticmethod\n' \
+                   '    def create(*args, **kwds):\n' \
+                   '        return AClass(*args, **kwds)\n' \
+                   'a_var = AClass.create(10)\n'
+        self._introduce_factory(mod, mod.read().index('AClass') + 1, 'create')
+        self.assertEquals(expected, mod.read())
+
+    def test_changing_occurances_in_other_modules(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('class AClass(object):\n    an_attr = 10\n')
+        mod2.write('import mod1\na_var = mod1.AClass()\n')
+        self._introduce_factory(mod1, mod1.read().index('AClass') + 1, 'create')
+        expected1 = 'class AClass(object):\n' \
+                    '    an_attr = 10\n\n' \
+                    '    @staticmethod\n' \
+                    '    def create(*args, **kwds):\n' \
+                    '        return AClass(*args, **kwds)\n'
+        expected2 = 'import mod1\n' \
+                    'a_var = mod1.AClass.create()\n'
+        self.assertEquals(expected1, mod1.read())
+        self.assertEquals(expected2, mod2.read())
+
+    @testutils.assert_raises(RefactoringError)
+    def test_raising_exception_for_non_classes(self):
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('def a_func():\n    pass\n')
+        self._introduce_factory(mod, mod.read().index('a_func') + 1, 'create')
+
+    def test_undoing_introduce_factory(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        code1 = 'class AClass(object):\n    an_attr = 10\n'
+        mod1.write(code1)
+        code2 = 'from mod1 import AClass\na_var = AClass()\n'
+        mod2.write(code2)
+        self._introduce_factory(mod1, mod1.read().index('AClass') + 1, 'create')
+        self.project.history.undo()
+        self.assertEquals(code1, mod1.read())
+        self.assertEquals(code2, mod2.read())
+
+    def test_using_on_an_occurance_outside_the_main_module(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('class AClass(object):\n    an_attr = 10\n')
+        mod2.write('import mod1\na_var = mod1.AClass()\n')
+        self._introduce_factory(mod2, mod2.read().index('AClass') + 1, 'create')
+        expected1 = 'class AClass(object):\n' \
+                    '    an_attr = 10\n\n' \
+                    '    @staticmethod\n' \
+                    '    def create(*args, **kwds):\n' \
+                    '        return AClass(*args, **kwds)\n'
+        expected2 = 'import mod1\n' \
+                    'a_var = mod1.AClass.create()\n'
+        self.assertEquals(expected1, mod1.read())
+        self.assertEquals(expected2, mod2.read())
+
+    def test_introduce_factory_in_nested_scopes(self):
+        code = 'def create_var():\n'\
+               '    class AClass(object):\n'\
+               '        an_attr = 10\n'\
+               '    return AClass()\n'
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write(code)
+        expected = 'def create_var():\n'\
+                   '    class AClass(object):\n'\
+                   '        an_attr = 10\n\n'\
+                   '        @staticmethod\n        def create(*args, **kwds):\n'\
+                   '            return AClass(*args, **kwds)\n'\
+                   '    return AClass.create()\n'
+        self._introduce_factory(mod, mod.read().index('AClass') + 1, 'create')
+        self.assertEquals(expected, mod.read())
+
+    def test_adding_factory_for_global_factories(self):
+        code = 'class AClass(object):\n    an_attr = 10\n'
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write(code)
+        expected = 'class AClass(object):\n' \
+                   '    an_attr = 10\n\n' \
+                   'def create(*args, **kwds):\n' \
+                   '    return AClass(*args, **kwds)\n'
+        self._introduce_factory(mod, mod.read().index('AClass') + 1,
+                                        'create', global_factory=True)
+        self.assertEquals(expected, mod.read())
+
+    def test_get_name_for_factories(self):
+        code = 'class C(object):\n    pass\n'
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write(code)
+        factory = IntroduceFactory(self.project, mod,
+                                   mod.read().index('C') + 1)
+        self.assertEquals('C', factory.get_name())
+
+    @testutils.assert_raises(RefactoringError)
+    def test_raising_exception_for_global_factory_for_nested_classes(self):
+        code = 'def create_var():\n'\
+               '    class AClass(object):\n'\
+               '        an_attr = 10\n'\
+               '    return AClass()\n'
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write(code)
+        self._introduce_factory(mod, mod.read().index('AClass') + 1,
+                                           'create', global_factory=True)
+
+    def test_changing_occurances_in_the_main_module_for_global_factories(self):
+        code = 'class AClass(object):\n' \
+               '    an_attr = 10\n' \
+               'a_var = AClass()'
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write(code)
+        expected = 'class AClass(object):\n    an_attr = 10\n\n' \
+                   'def create(*args, **kwds):\n' \
+                   '    return AClass(*args, **kwds)\n'\
+                   'a_var = create()'
+        self._introduce_factory(mod, mod.read().index('AClass') + 1,
+                                           'create', global_factory=True)
+        self.assertEquals(expected, mod.read())
+
+    def test_changing_occurances_in_other_modules_for_global_factories(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('class AClass(object):\n    an_attr = 10\n')
+        mod2.write('import mod1\na_var = mod1.AClass()\n')
+        self._introduce_factory(mod1, mod1.read().index('AClass') + 1,
+                                           'create', global_factory=True)
+        expected1 = 'class AClass(object):\n' \
+                    '    an_attr = 10\n\n' \
+                    'def create(*args, **kwds):\n' \
+                    '    return AClass(*args, **kwds)\n'
+        expected2 = 'import mod1\n' \
+                    'a_var = mod1.create()\n'
+        self.assertEquals(expected1, mod1.read())
+        self.assertEquals(expected2, mod2.read())
+
+    def test_importing_if_necessary_in_other_modules_for_global_factories(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('class AClass(object):\n    an_attr = 10\n')
+        mod2.write('from mod1 import AClass\npair = AClass(), AClass\n')
+        self._introduce_factory(mod1, mod1.read().index('AClass') + 1,
+                                           'create', global_factory=True)
+        expected1 = 'class AClass(object):\n' \
+                    '    an_attr = 10\n\n' \
+                    'def create(*args, **kwds):\n' \
+                    '    return AClass(*args, **kwds)\n'
+        expected2 = 'from mod1 import AClass, create\n' \
+                    'pair = create(), AClass\n'
+        self.assertEquals(expected1, mod1.read())
+        self.assertEquals(expected2, mod2.read())
+
+    def test_changing_occurances_for_renamed_classes(self):
+        code = 'class AClass(object):\n    an_attr = 10\na_class = AClass\na_var = a_class()'
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write(code)
+        expected = 'class AClass(object):\n' \
+                   '    an_attr = 10\n\n' \
+                   '    @staticmethod\n' \
+                   '    def create(*args, **kwds):\n' \
+                   '        return AClass(*args, **kwds)\n' \
+                   'a_class = AClass\n' \
+                   'a_var = a_class()'
+        self._introduce_factory(mod, mod.read().index('a_class') + 1, 'create')
+        self.assertEquals(expected, mod.read())
+
+    def test_changing_occurrences_in_the_same_module_with_conflicting_ranges(self):
+        mod = testutils.create_module(self.project, 'mod')
+        code = 'class C(object):\n' \
+               '    def create(self):\n' \
+               '        return C()\n'
+        mod.write(code)
+        self._introduce_factory(mod, mod.read().index('C'), 'create_c', True)
+        expected = 'class C(object):\n' \
+                   '    def create(self):\n' \
+                   '        return create_c()\n'
+        self.assertTrue(mod.read().startswith(expected))
+
+    def _transform_module_to_package(self, resource):
+        self.project.do(rope.refactor.ModuleToPackage(
+                        self.project, resource).get_changes())
+
+    def test_transform_module_to_package(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('import mod2\nfrom mod2 import AClass\n')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod2.write('class AClass(object):\n    pass\n')
+        self._transform_module_to_package(mod2)
+        mod2 = self.project.get_resource('mod2')
+        root_folder = self.project.root
+        self.assertFalse(root_folder.has_child('mod2.py'))
+        self.assertEquals('class AClass(object):\n    pass\n',
+                          root_folder.get_child('mod2').
+                          get_child('__init__.py').read())
+
+    def test_transform_module_to_package_undoing(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod = testutils.create_module(self.project, 'mod', pkg)
+        self._transform_module_to_package(mod)
+        self.assertFalse(pkg.has_child('mod.py'))
+        self.assertTrue(pkg.get_child('mod').has_child('__init__.py'))
+        self.project.history.undo()
+        self.assertTrue(pkg.has_child('mod.py'))
+        self.assertFalse(pkg.has_child('mod'))
+
+    def test_transform_module_to_package_with_relative_imports(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1 = testutils.create_module(self.project, 'mod1', pkg)
+        mod1.write('import mod2\nfrom mod2 import AClass\n')
+        mod2 = testutils.create_module(self.project, 'mod2', pkg)
+        mod2.write('class AClass(object):\n    pass\n')
+        self._transform_module_to_package(mod1)
+        new_init = self.project.get_resource('pkg/mod1/__init__.py')
+        self.assertEquals('import pkg.mod2\nfrom pkg.mod2 import AClass\n',
+                          new_init.read())
+
+    def test_resources_parameter(self):
+        code = 'class A(object):\n    an_attr = 10\n'
+        code1 = 'import mod\na = mod.A()\n'
+        mod = testutils.create_module(self.project, 'mod')
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod.write(code)
+        mod1.write(code1)
+        expected = 'class A(object):\n' \
+                   '    an_attr = 10\n\n' \
+                   '    @staticmethod\n' \
+                   '    def create(*args, **kwds):\n' \
+                   '        return A(*args, **kwds)\n'
+        self._introduce_factory(mod, mod.read().index('A') + 1,
+                                'create', resources=[mod])
+        self.assertEquals(expected, mod.read())
+        self.assertEquals(code1, mod1.read())
+
+
+class EncapsulateFieldTest(unittest.TestCase):
+
+    def setUp(self):
+        super(EncapsulateFieldTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+        self.mod = testutils.create_module(self.project, 'mod')
+        self.mod1 = testutils.create_module(self.project, 'mod1')
+        self.a_class = 'class A(object):\n' \
+                       '    def __init__(self):\n' \
+                       '        self.attr = 1\n'
+        self.added_methods = '\n' \
+            '    def get_attr(self):\n' \
+            '        return self.attr\n\n' \
+            '    def set_attr(self, value):\n' \
+            '        self.attr = value\n'
+        self.encapsulated = self.a_class + self.added_methods
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(EncapsulateFieldTest, self).tearDown()
+
+    def _encapsulate(self, resource, offset, **args):
+        changes = EncapsulateField(self.project, resource, offset).\
+                  get_changes(**args)
+        self.project.do(changes)
+
+    def test_adding_getters_and_setters(self):
+        code = self.a_class
+        self.mod.write(code)
+        self._encapsulate(self.mod, code.index('attr') + 1)
+        self.assertEquals(self.encapsulated, self.mod.read())
+
+    def test_changing_getters_in_other_modules(self):
+        code = 'import mod\n' \
+               'a_var = mod.A()\n' \
+               'range(a_var.attr)\n'
+        self.mod1.write(code)
+        self.mod.write(self.a_class)
+        self._encapsulate(self.mod, self.mod.read().index('attr') + 1)
+        expected = 'import mod\n' \
+                   'a_var = mod.A()\n' \
+                   'range(a_var.get_attr())\n'
+        self.assertEquals(expected, self.mod1.read())
+
+    def test_changing_setters_in_other_modules(self):
+        code = 'import mod\n' \
+               'a_var = mod.A()\n' \
+               'a_var.attr = 1\n'
+        self.mod1.write(code)
+        self.mod.write(self.a_class)
+        self._encapsulate(self.mod, self.mod.read().index('attr') + 1)
+        expected = 'import mod\n' \
+                   'a_var = mod.A()\n' \
+                   'a_var.set_attr(1)\n'
+        self.assertEquals(expected, self.mod1.read())
+
+    def test_changing_getters_in_setters(self):
+        code = 'import mod\n' \
+               'a_var = mod.A()\n' \
+               'a_var.attr = 1 + a_var.attr\n'
+        self.mod1.write(code)
+        self.mod.write(self.a_class)
+        self._encapsulate(self.mod, self.mod.read().index('attr') + 1)
+        expected = 'import mod\n' \
+                   'a_var = mod.A()\n' \
+                   'a_var.set_attr(1 + a_var.get_attr())\n'
+        self.assertEquals(expected, self.mod1.read())
+
+    def test_appending_to_class_end(self):
+        self.mod1.write(self.a_class + 'a_var = A()\n')
+        self._encapsulate(self.mod1, self.mod1.read().index('attr') + 1)
+        self.assertEquals(self.encapsulated + 'a_var = A()\n',
+                          self.mod1.read())
+
+    def test_performing_in_other_modules(self):
+        code = 'import mod\n' \
+               'a_var = mod.A()\n' \
+               'range(a_var.attr)\n'
+        self.mod1.write(code)
+        self.mod.write(self.a_class)
+        self._encapsulate(self.mod1, self.mod1.read().index('attr') + 1)
+        self.assertEquals(self.encapsulated, self.mod.read())
+        expected = 'import mod\n' \
+                   'a_var = mod.A()\n' \
+                   'range(a_var.get_attr())\n'
+        self.assertEquals(expected, self.mod1.read())
+
+    def test_changing_main_module_occurances(self):
+        code = self.a_class + \
+               'a_var = A()\n' \
+               'a_var.attr = a_var.attr * 2\n'
+        self.mod1.write(code)
+        self._encapsulate(self.mod1, self.mod1.read().index('attr') + 1)
+        expected = self.encapsulated + \
+                   'a_var = A()\n' \
+                   'a_var.set_attr(a_var.get_attr() * 2)\n'
+        self.assertEquals(expected, self.mod1.read())
+
+    @testutils.assert_raises(RefactoringError)
+    def test_raising_exception_when_performed_on_non_attributes(self):
+        self.mod1.write('attr = 10')
+        self._encapsulate(self.mod1, self.mod1.read().index('attr') + 1)
+
+    @testutils.assert_raises(RefactoringError)
+    def test_raising_exception_on_tuple_assignments(self):
+        self.mod.write(self.a_class)
+        code = 'import mod\n' \
+               'a_var = mod.A()\n' \
+               'a_var.attr = 1\n' \
+               'a_var.attr, b = 1, 2\n'
+        self.mod1.write(code)
+        self._encapsulate(self.mod1, self.mod1.read().index('attr') + 1)
+
+    @testutils.assert_raises(RefactoringError)
+    def test_raising_exception_on_tuple_assignments2(self):
+        self.mod.write(self.a_class)
+        code = 'import mod\n' \
+               'a_var = mod.A()\n' \
+               'a_var.attr = 1\n' \
+               'b, a_var.attr = 1, 2\n'
+        self.mod1.write(code)
+        self._encapsulate(self.mod1, self.mod1.read().index('attr') + 1)
+
+    def test_tuple_assignments_and_function_calls(self):
+        code = 'import mod\n' \
+               'def func(a1=0, a2=0):\n' \
+               '    pass\n' \
+               'a_var = mod.A()\n' \
+               'func(a_var.attr, a2=2)\n'
+        self.mod1.write(code)
+        self.mod.write(self.a_class)
+        self._encapsulate(self.mod, self.mod.read().index('attr') + 1)
+        expected = 'import mod\n' \
+                   'def func(a1=0, a2=0):\n' \
+                   '    pass\n' \
+                   'a_var = mod.A()\n' \
+                   'func(a_var.get_attr(), a2=2)\n'
+        self.assertEquals(expected, self.mod1.read())
+
+    def test_tuple_assignments(self):
+        code = 'import mod\n' \
+               'a_var = mod.A()\n' \
+               'a, b = a_var.attr, 1\n'
+        self.mod1.write(code)
+        self.mod.write(self.a_class)
+        self._encapsulate(self.mod, self.mod.read().index('attr') + 1)
+        expected = 'import mod\n' \
+                   'a_var = mod.A()\n' \
+                   'a, b = a_var.get_attr(), 1\n'
+        self.assertEquals(expected, self.mod1.read())
+
+    def test_changing_augmented_assignments(self):
+        code = 'import mod\n' \
+               'a_var = mod.A()\n' \
+               'a_var.attr += 1\n'
+        self.mod1.write(code)
+        self.mod.write(self.a_class)
+        self._encapsulate(self.mod, self.mod.read().index('attr') + 1)
+        expected = 'import mod\n' \
+                   'a_var = mod.A()\n' \
+                   'a_var.set_attr(a_var.get_attr() + 1)\n'
+        self.assertEquals(expected, self.mod1.read())
+
+    def test_changing_augmented_assignments2(self):
+        code = 'import mod\n' \
+               'a_var = mod.A()\n' \
+               'a_var.attr <<= 1\n'
+        self.mod1.write(code)
+        self.mod.write(self.a_class)
+        self._encapsulate(self.mod, self.mod.read().index('attr') + 1)
+        expected = 'import mod\n' \
+                   'a_var = mod.A()\n' \
+                   'a_var.set_attr(a_var.get_attr() << 1)\n'
+        self.assertEquals(expected, self.mod1.read())
+
+    def test_changing_occurrences_inside_the_class(self):
+        new_class = self.a_class + '\n' \
+                    '    def a_func(self):\n' \
+                    '        self.attr = 1\n'
+        self.mod.write(new_class)
+        self._encapsulate(self.mod, self.mod.read().index('attr') + 1)
+        expected = self.a_class + '\n' \
+                   '    def a_func(self):\n' \
+                   '        self.set_attr(1)\n' + \
+                   self.added_methods
+        self.assertEquals(expected, self.mod.read())
+
+    def test_getter_and_setter_parameters(self):
+        self.mod.write(self.a_class)
+        self._encapsulate(self.mod, self.mod.read().index('attr') + 1,
+                          getter='getAttr', setter='setAttr')
+        new_methods = self.added_methods.replace('get_attr', 'getAttr').\
+                      replace('set_attr', 'setAttr')
+        expected = self.a_class + new_methods
+        self.assertEquals(expected, self.mod.read())
+
+    def test_using_resources_parameter(self):
+        self.mod1.write('import mod\na = mod.A()\nvar = a.attr\n')
+        self.mod.write(self.a_class)
+        self._encapsulate(self.mod, self.mod.read().index('attr') + 1,
+                          resources=[self.mod])
+        self.assertEquals('import mod\na = mod.A()\nvar = a.attr\n',
+                          self.mod1.read())
+        expected = self.a_class + self.added_methods
+        self.assertEquals(expected, self.mod.read())
+
+
+class LocalToFieldTest(unittest.TestCase):
+
+    def setUp(self):
+        super(LocalToFieldTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+        self.mod = testutils.create_module(self.project, 'mod')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(LocalToFieldTest, self).tearDown()
+
+    def _perform_convert_local_variable_to_field(self, resource, offset):
+        changes = LocalToField(
+            self.project, resource, offset).get_changes()
+        self.project.do(changes)
+
+    def test_simple_local_to_field(self):
+        code = 'class A(object):\n' \
+               '    def a_func(self):\n' \
+               '        var = 10\n'
+        self.mod.write(code)
+        self._perform_convert_local_variable_to_field(self.mod,
+                                                      code.index('var') + 1)
+        expected = 'class A(object):\n' \
+                   '    def a_func(self):\n' \
+                   '        self.var = 10\n'
+        self.assertEquals(expected, self.mod.read())
+
+    @testutils.assert_raises(RefactoringError)
+    def test_raising_exception_when_performed_on_a_global_var(self):
+        self.mod.write('var = 10\n')
+        self._perform_convert_local_variable_to_field(
+            self.mod, self.mod.read().index('var') + 1)
+
+    @testutils.assert_raises(RefactoringError)
+    def test_raising_exception_when_performed_on_field(self):
+        code = 'class A(object):\n' \
+               '    def a_func(self):\n' \
+               '        self.var = 10\n'
+        self.mod.write(code)
+        self._perform_convert_local_variable_to_field(
+            self.mod, self.mod.read().index('var') + 1)
+
+    @testutils.assert_raises(RefactoringError)
+    def test_raising_exception_when_performed_on_a_parameter(self):
+        code = 'class A(object):\n' \
+               '    def a_func(self, var):\n' \
+               '        a = var\n'
+        self.mod.write(code)
+        self._perform_convert_local_variable_to_field(
+            self.mod, self.mod.read().index('var') + 1)
+
+    # NOTE: This situation happens alot and is normally not an error
+    #@testutils.assert_raises(RefactoringError)
+    def test_not_raising_exception_when_there_is_a_field_with_the_same_name(self):
+        code = 'class A(object):\n' \
+               '    def __init__(self):\n' \
+               '        self.var = 1\n' \
+               '    def a_func(self):\n        var = 10\n'
+        self.mod.write(code)
+        self._perform_convert_local_variable_to_field(
+            self.mod, self.mod.read().rindex('var') + 1)
+
+    def test_local_to_field_with_self_renamed(self):
+        code = 'class A(object):\n' \
+               '    def a_func(myself):\n' \
+               '        var = 10\n'
+        self.mod.write(code)
+        self._perform_convert_local_variable_to_field(self.mod,
+                                                         code.index('var') + 1)
+        expected = 'class A(object):\n' \
+                   '    def a_func(myself):\n' \
+                   '        myself.var = 10\n'
+        self.assertEquals(expected, self.mod.read())
+
+
+class IntroduceParameterTest(unittest.TestCase):
+
+    def setUp(self):
+        super(IntroduceParameterTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+        self.mod = testutils.create_module(self.project, 'mod')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(IntroduceParameterTest, self).tearDown()
+
+    def _introduce_parameter(self, offset, name):
+        rope.refactor.introduce_parameter.IntroduceParameter(
+            self.project, self.mod, offset).get_changes(name).do()
+
+    def test_simple_case(self):
+        code = 'var = 1\n' \
+               'def f():\n' \
+               '    b = var\n'
+        self.mod.write(code)
+        offset = self.mod.read().rindex('var')
+        self._introduce_parameter(offset, 'var')
+        expected = 'var = 1\n' \
+                   'def f(var=var):\n' \
+                   '    b = var\n'
+        self.assertEquals(expected, self.mod.read())
+
+    def test_changing_function_body(self):
+        code = 'var = 1\n' \
+               'def f():\n' \
+               '    b = var\n'
+        self.mod.write(code)
+        offset = self.mod.read().rindex('var')
+        self._introduce_parameter(offset, 'p1')
+        expected = 'var = 1\n' \
+                   'def f(p1=var):\n' \
+                   '    b = p1\n'
+        self.assertEquals(expected, self.mod.read())
+
+    @testutils.assert_raises(RefactoringError)
+    def test_unknown_variables(self):
+        self.mod.write('def f():\n    b = var + c\n')
+        offset = self.mod.read().rindex('var')
+        self._introduce_parameter(offset, 'p1')
+        self.assertEquals('def f(p1=var):\n    b = p1 + c\n',
+                          self.mod.read())
+
+    @testutils.assert_raises(RefactoringError)
+    def test_failing_when_not_inside(self):
+        self.mod.write('var = 10\nb = var\n')
+        offset = self.mod.read().rindex('var')
+        self._introduce_parameter(offset, 'p1')
+
+    def test_attribute_accesses(self):
+        code = 'class C(object):\n' \
+               '    a = 10\nc = C()\n' \
+               'def f():\n' \
+               '    b = c.a\n'
+        self.mod.write(code)
+        offset = self.mod.read().rindex('a')
+        self._introduce_parameter(offset, 'p1')
+        expected = 'class C(object):\n' \
+                   '    a = 10\n' \
+                   'c = C()\n' \
+                   'def f(p1=c.a):\n' \
+                   '    b = p1\n'
+        self.assertEquals(expected, self.mod.read())
+
+    def test_introducing_parameters_for_methods(self):
+        code = 'var = 1\n' \
+               'class C(object):\n' \
+               '    def f(self):\n' \
+               '        b = var\n'
+        self.mod.write(code)
+        offset = self.mod.read().rindex('var')
+        self._introduce_parameter(offset, 'p1')
+        expected = 'var = 1\n' \
+                   'class C(object):\n' \
+                   '    def f(self, p1=var):\n' \
+                   '        b = p1\n'
+        self.assertEquals(expected, self.mod.read())
+
+
+class _MockTaskObserver(object):
+
+    def __init__(self):
+        self.called = 0
+
+    def __call__(self):
+        self.called += 1
+
+class TaskHandleTest(unittest.TestCase):
+
+    def test_trivial_case(self):
+        handle = rope.base.taskhandle.TaskHandle()
+        self.assertFalse(handle.is_stopped())
+
+    def test_stopping(self):
+        handle = rope.base.taskhandle.TaskHandle()
+        handle.stop()
+        self.assertTrue(handle.is_stopped())
+
+    def test_job_sets(self):
+        handle = rope.base.taskhandle.TaskHandle()
+        jobs = handle.create_jobset()
+        self.assertEquals([jobs], handle.get_jobsets())
+
+    def test_starting_and_finishing_jobs(self):
+        handle = rope.base.taskhandle.TaskHandle()
+        jobs = handle.create_jobset(name='test job set', count=1)
+        jobs.started_job('job1')
+        jobs.finished_job()
+
+    @testutils.assert_raises(InterruptedTaskError)
+    def test_test_checking_status(self):
+        handle = rope.base.taskhandle.TaskHandle()
+        jobs = handle.create_jobset()
+        handle.stop()
+        jobs.check_status()
+
+    @testutils.assert_raises(InterruptedTaskError)
+    def test_test_checking_status_when_starting(self):
+        handle = rope.base.taskhandle.TaskHandle()
+        jobs = handle.create_jobset()
+        handle.stop()
+        jobs.started_job('job1')
+
+    def test_calling_the_observer_after_stopping(self):
+        handle = rope.base.taskhandle.TaskHandle()
+        observer = _MockTaskObserver()
+        handle.add_observer(observer)
+        handle.stop()
+        self.assertEquals(1, observer.called)
+
+    def test_calling_the_observer_after_creating_job_sets(self):
+        handle = rope.base.taskhandle.TaskHandle()
+        observer = _MockTaskObserver()
+        handle.add_observer(observer)
+        jobs = handle.create_jobset()
+        self.assertEquals(1, observer.called)
+
+    def test_calling_the_observer_when_starting_and_finishing_jobs(self):
+        handle = rope.base.taskhandle.TaskHandle()
+        observer = _MockTaskObserver()
+        handle.add_observer(observer)
+        jobs = handle.create_jobset(name='test job set', count=1)
+        jobs.started_job('job1')
+        jobs.finished_job()
+        self.assertEquals(3, observer.called)
+
+    def test_job_set_get_percent_done(self):
+        handle = rope.base.taskhandle.TaskHandle()
+        jobs = handle.create_jobset(name='test job set', count=2)
+        self.assertEquals(0, jobs.get_percent_done())
+        jobs.started_job('job1')
+        jobs.finished_job()
+        self.assertEquals(50, jobs.get_percent_done())
+        jobs.started_job('job2')
+        jobs.finished_job()
+        self.assertEquals(100, jobs.get_percent_done())
+
+    def test_getting_job_name(self):
+        handle = rope.base.taskhandle.TaskHandle()
+        jobs = handle.create_jobset(name='test job set', count=1)
+        self.assertEquals('test job set', jobs.get_name())
+        self.assertEquals(None, jobs.get_active_job_name())
+        jobs.started_job('job1')
+        self.assertEquals('job1', jobs.get_active_job_name())
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(ropetest.refactor.renametest.suite())
+    result.addTests(unittest.makeSuite(
+                    ropetest.refactor.extracttest.ExtractMethodTest))
+    result.addTests(unittest.makeSuite(IntroduceFactoryTest))
+    result.addTests(unittest.makeSuite(
+                    ropetest.refactor.movetest.MoveRefactoringTest))
+    result.addTests(ropetest.refactor.inlinetest.suite())
+    result.addTests(unittest.makeSuite(
+                    ropetest.refactor.patchedasttest.PatchedASTTest))
+    result.addTests(unittest.makeSuite(EncapsulateFieldTest))
+    result.addTests(unittest.makeSuite(LocalToFieldTest))
+    result.addTests(unittest.makeSuite(
+                    change_signature_test.ChangeSignatureTest))
+    result.addTests(unittest.makeSuite(IntroduceParameterTest))
+    result.addTests(ropetest.refactor.importutilstest.suite())
+    result.addTests(similarfindertest.suite())
+    result.addTests(unittest.makeSuite(TaskHandleTest))
+    result.addTests(unittest.makeSuite(ropetest.refactor.
+                                       restructuretest.RestructureTest))
+    result.addTests(unittest.makeSuite(ropetest.refactor.
+                                       suitestest.SuiteTest))
+    result.addTests(unittest.makeSuite(ropetest.refactor.multiprojecttest.
+                                       MultiProjectRefactoringTest))
+    result.addTests(unittest.makeSuite(ropetest.refactor.usefunctiontest.
+                                       UseFunctionTest))
+    return result
+
+
+if __name__ == '__main__':
+    import sys
+    if len(sys.argv) > 1:
+        unittest.main()
+    else:
+        runner = unittest.TextTestRunner()
+        result = runner.run(suite())
+        sys.exit(not result.wasSuccessful())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/refactor/change_signature_test.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,413 @@
+import unittest
+
+import rope.base.exceptions
+from rope.refactor import change_signature
+from rope.refactor.change_signature import *
+from ropetest import testutils
+
+
+class ChangeSignatureTest(unittest.TestCase):
+
+    def setUp(self):
+        super(ChangeSignatureTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+        self.mod = testutils.create_module(self.project, 'mod')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(ChangeSignatureTest, self).tearDown()
+
+    def test_normalizing_parameters_for_trivial_case(self):
+        code = 'def a_func():\n    pass\na_func()'
+        self.mod.write(code)
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentNormalizer()]))
+        self.assertEquals(code, self.mod.read())
+
+    def test_normalizing_parameters_for_trivial_case2(self):
+        code = 'def a_func(param):\n    pass\na_func(2)'
+        self.mod.write(code)
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentNormalizer()]))
+        self.assertEquals(code, self.mod.read())
+
+    def test_normalizing_parameters_for_unneeded_keyword(self):
+        self.mod.write('def a_func(param):\n    pass\na_func(param=1)')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentNormalizer()]))
+        self.assertEquals('def a_func(param):\n    pass\na_func(1)', self.mod.read())
+
+    def test_normalizing_parameters_for_unneeded_keyword_for_methods(self):
+        code = 'class A(object):\n' \
+               '    def a_func(self, param):\n' \
+               '        pass\n' \
+               'a_var = A()\n' \
+               'a_var.a_func(param=1)\n'
+        self.mod.write(code)
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentNormalizer()]))
+        expected = 'class A(object):\n' \
+                   '    def a_func(self, param):\n' \
+                   '        pass\n' \
+                   'a_var = A()\n' \
+                   'a_var.a_func(1)\n'
+        self.assertEquals(expected, self.mod.read())
+
+    def test_normalizing_parameters_for_unsorted_keyword(self):
+        self.mod.write('def a_func(p1, p2):\n    pass\na_func(p2=2, p1=1)')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentNormalizer()]))
+        self.assertEquals('def a_func(p1, p2):\n    pass\na_func(1, 2)',
+                          self.mod.read())
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_raising_exceptions_for_non_functions(self):
+        self.mod.write('a_var = 10')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_var') + 1)
+
+    def test_normalizing_parameters_for_args_parameter(self):
+        self.mod.write('def a_func(*arg):\n    pass\na_func(1, 2)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentNormalizer()]))
+        self.assertEquals('def a_func(*arg):\n    pass\na_func(1, 2)\n',
+                          self.mod.read())
+
+    def test_normalizing_parameters_for_args_parameter_and_keywords(self):
+        self.mod.write('def a_func(param, *args):\n    pass\na_func(*[1, 2, 3])\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentNormalizer()]))
+        self.assertEquals('def a_func(param, *args):\n    pass\n'
+                          'a_func(*[1, 2, 3])\n', self.mod.read())
+
+    def test_normalizing_functions_from_other_modules(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('def a_func(param):\n    pass\n')
+        self.mod.write('import mod1\nmod1.a_func(param=1)\n')
+        signature = ChangeSignature(self.project, mod1,
+                                    mod1.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentNormalizer()]))
+        self.assertEquals('import mod1\nmod1.a_func(1)\n', self.mod.read())
+
+    def test_normalizing_parameters_for_keyword_parameters(self):
+        self.mod.write('def a_func(p1, **kwds):\n    pass\n'
+                       'a_func(p2=2, p1=1)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentNormalizer()]))
+        self.assertEquals('def a_func(p1, **kwds):\n    pass\n'
+                          'a_func(1, p2=2)\n', self.mod.read())
+
+    def test_removing_arguments(self):
+        self.mod.write('def a_func(p1):\n    pass\na_func(1)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentRemover(0)]))
+        self.assertEquals('def a_func():\n    pass\na_func()\n',
+                          self.mod.read())
+
+    def test_removing_arguments_with_multiple_args(self):
+        self.mod.write('def a_func(p1, p2):\n    pass\na_func(1, 2)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentRemover(0)]))
+        self.assertEquals('def a_func(p2):\n    pass\na_func(2)\n',
+                          self.mod.read())
+
+    def test_removing_arguments_passed_as_keywords(self):
+        self.mod.write('def a_func(p1):\n    pass\na_func(p1=1)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentRemover(0)]))
+        self.assertEquals('def a_func():\n    pass\na_func()\n',
+                          self.mod.read())
+
+    def test_removing_arguments_with_defaults(self):
+        self.mod.write('def a_func(p1=1):\n    pass\na_func(1)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentRemover(0)]))
+        self.assertEquals('def a_func():\n    pass\na_func()\n',
+                          self.mod.read())
+
+    def test_removing_arguments_star_args(self):
+        self.mod.write('def a_func(p1, *args):\n    pass\na_func(1)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentRemover(1)]))
+        self.assertEquals('def a_func(p1):\n    pass\na_func(1)\n',
+                          self.mod.read())
+
+    def test_removing_keyword_arg(self):
+        self.mod.write('def a_func(p1, **kwds):\n    pass\na_func(1)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentRemover(1)]))
+        self.assertEquals('def a_func(p1):\n    pass\na_func(1)\n',
+                          self.mod.read())
+
+    def test_removing_keyword_arg2(self):
+        self.mod.write('def a_func(p1, *args, **kwds):\n    pass\na_func(1)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentRemover(2)]))
+        self.assertEquals('def a_func(p1, *args):\n    pass\na_func(1)\n',
+                          self.mod.read())
+
+    # XXX: What to do here for star args?
+    def xxx_test_removing_arguments_star_args2(self):
+        self.mod.write('def a_func(p1, *args):\n    pass\n'
+                       'a_func(2, 3, p1=1)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentRemover(1)]))
+        self.assertEquals('def a_func(p1):\n    pass\na_func(p1=1)\n',
+                          self.mod.read())
+
+    # XXX: What to do here for star args?
+    def xxx_test_removing_arguments_star_args3(self):
+        self.mod.write('def a_func(p1, *args):\n    pass\n'
+                       'a_func(*[1, 2, 3])\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentRemover(1)]))
+        self.assertEquals('def a_func(p1):\n    pass\na_func(*[1, 2, 3])\n',
+                          self.mod.read())
+
+    def test_adding_arguments_for_normal_args_changing_definition(self):
+        self.mod.write('def a_func():\n    pass\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentAdder(0, 'p1')]))
+        self.assertEquals('def a_func(p1):\n    pass\n', self.mod.read())
+
+    def test_adding_arguments_for_normal_args_with_defaults(self):
+        self.mod.write('def a_func():\n    pass\na_func()\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        adder = ArgumentAdder(0, 'p1', 'None')
+        self.project.do(signature.get_changes([adder]))
+        self.assertEquals('def a_func(p1=None):\n    pass\na_func()\n',
+                          self.mod.read())
+
+    def test_adding_arguments_for_normal_args_changing_calls(self):
+        self.mod.write('def a_func():\n    pass\na_func()\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        adder = ArgumentAdder(0, 'p1', 'None', '1')
+        self.project.do(signature.get_changes([adder]))
+        self.assertEquals('def a_func(p1=None):\n    pass\na_func(1)\n',
+                          self.mod.read())
+
+    def test_adding_arguments_for_normal_args_changing_calls_with_keywords(self):
+        self.mod.write('def a_func(p1=0):\n    pass\na_func()\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        adder = ArgumentAdder(1, 'p2', '0', '1')
+        self.project.do(signature.get_changes([adder]))
+        self.assertEquals('def a_func(p1=0, p2=0):\n    pass\na_func(p2=1)\n',
+                          self.mod.read())
+
+    def test_adding_arguments_for_normal_args_changing_calls_with_no_value(self):
+        self.mod.write('def a_func(p2=0):\n    pass\na_func(1)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        adder = ArgumentAdder(0, 'p1', '0', None)
+        self.project.do(signature.get_changes([adder]))
+        self.assertEquals('def a_func(p1=0, p2=0):\n    pass\na_func(p2=1)\n',
+                          self.mod.read())
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_adding_duplicate_parameter_and_raising_exceptions(self):
+        self.mod.write('def a_func(p1):\n    pass\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentAdder(1, 'p1')]))
+
+    def test_inlining_default_arguments(self):
+        self.mod.write('def a_func(p1=0):\n    pass\na_func()\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentDefaultInliner(0)]))
+        self.assertEquals('def a_func(p1=0):\n    pass\n'
+                          'a_func(0)\n', self.mod.read())
+
+    def test_inlining_default_arguments2(self):
+        self.mod.write('def a_func(p1=0):\n    pass\na_func(1)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentDefaultInliner(0)]))
+        self.assertEquals('def a_func(p1=0):\n    pass\n'
+                          'a_func(1)\n', self.mod.read())
+
+    def test_preserving_args_and_keywords_order(self):
+        self.mod.write('def a_func(*args, **kwds):\n    pass\n'
+                       'a_func(3, 1, 2, a=1, c=3, b=2)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentNormalizer()]))
+        self.assertEquals('def a_func(*args, **kwds):\n    pass\n'
+                          'a_func(3, 1, 2, a=1, c=3, b=2)\n', self.mod.read())
+
+    def test_change_order_for_only_one_parameter(self):
+        self.mod.write('def a_func(p1):\n    pass\na_func(1)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentReorderer([0])]))
+        self.assertEquals('def a_func(p1):\n    pass\na_func(1)\n',
+                          self.mod.read())
+
+    def test_change_order_for_two_parameter(self):
+        self.mod.write('def a_func(p1, p2):\n    pass\na_func(1, 2)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentReorderer([1, 0])]))
+        self.assertEquals('def a_func(p2, p1):\n    pass\na_func(2, 1)\n',
+                          self.mod.read())
+
+    def test_reordering_multi_line_function_headers(self):
+        self.mod.write('def a_func(p1,\n p2):\n    pass\na_func(1, 2)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentReorderer([1, 0])]))
+        self.assertEquals('def a_func(p2, p1):\n    pass\na_func(2, 1)\n',
+                          self.mod.read())
+
+    def test_changing_order_with_static_params(self):
+        self.mod.write('def a_func(p1, p2=0, p3=0):\n    pass\na_func(1, 2)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentReorderer([0, 2, 1])]))
+        self.assertEquals('def a_func(p1, p3=0, p2=0):\n    pass\n'
+                          'a_func(1, p2=2)\n', self.mod.read())
+
+    def test_doing_multiple_changes(self):
+        changers = []
+        self.mod.write('def a_func(p1):\n    pass\na_func(1)\n')
+        changers.append(change_signature.ArgumentRemover(0))
+        changers.append(change_signature.ArgumentAdder(0, 'p2', None, None))
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        signature.get_changes(changers).do()
+        self.assertEquals('def a_func(p2):\n    pass\na_func()\n',
+                          self.mod.read())
+
+    def test_doing_multiple_changes2(self):
+        changers = []
+        self.mod.write('def a_func(p1, p2):\n    pass\na_func(p2=2)\n')
+        changers.append(change_signature.ArgumentAdder(2, 'p3', None, '3'))
+        changers.append(change_signature.ArgumentReorderer([1, 0, 2]))
+        changers.append(change_signature.ArgumentRemover(1))
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        signature.get_changes(changers).do()
+        self.assertEquals('def a_func(p2, p3):\n    pass\na_func(2, 3)\n',
+                          self.mod.read())
+
+    def test_changing_signature_in_subclasses(self):
+        self.mod.write(
+            'class A(object):\n    def a_method(self):\n        pass\n'
+            'class B(A):\n    def a_method(self):\n        pass\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_method') + 1)
+        signature.get_changes([change_signature.ArgumentAdder(1, 'p1')],
+                                 in_hierarchy=True).do()
+        self.assertEquals(
+            'class A(object):\n    def a_method(self, p1):\n        pass\n'
+            'class B(A):\n    def a_method(self, p1):\n        pass\n',
+            self.mod.read())
+
+    def test_differentiating_class_accesses_from_instance_accesses(self):
+        self.mod.write(
+            'class A(object):\n    def a_func(self, param):\n        pass\n'
+            'a_var = A()\nA.a_func(a_var, param=1)')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('a_func') + 1)
+        self.project.do(signature.get_changes([ArgumentRemover(1)]))
+        self.assertEquals(
+            'class A(object):\n    def a_func(self):\n        pass\n'
+            'a_var = A()\nA.a_func(a_var)', self.mod.read())
+
+    def test_changing_signature_for_constructors(self):
+        self.mod.write(
+            'class C(object):\n    def __init__(self, p):\n        pass\n'
+            'c = C(1)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('C') + 1)
+        signature.get_changes([change_signature.ArgumentRemover(1)]).do()
+        self.assertEquals(
+            'class C(object):\n    def __init__(self):\n        pass\n'
+            'c = C()\n',
+            self.mod.read())
+
+    def test_changing_signature_for_constructors2(self):
+        self.mod.write(
+            'class C(object):\n    def __init__(self, p):\n        pass\n'
+            'c = C(1)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('__init__') + 1)
+        signature.get_changes([change_signature.ArgumentRemover(1)]).do()
+        self.assertEquals(
+            'class C(object):\n    def __init__(self):\n        pass\n'
+            'c = C()\n',
+            self.mod.read())
+
+    def test_changing_signature_for_constructors_when_using_super(self):
+        self.mod.write(
+            'class A(object):\n    def __init__(self, p):\n        pass\n'
+            'class B(A):\n    '
+            'def __init__(self, p):\n        super(B, self).__init__(p)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().index('__init__') + 1)
+        signature.get_changes([change_signature.ArgumentRemover(1)]).do()
+        self.assertEquals(
+            'class A(object):\n    def __init__(self):\n        pass\n'
+            'class B(A):\n    '
+            'def __init__(self, p):\n        super(B, self).__init__()\n',
+            self.mod.read())
+
+    def test_redordering_arguments_reported_by_mft(self):
+        self.mod.write('def f(a, b, c):\n    pass\nf(1, 2, 3)\n')
+        signature = ChangeSignature(self.project, self.mod,
+                                    self.mod.read().rindex('f'))
+        signature.get_changes(
+            [change_signature.ArgumentReorderer([1, 2, 0])]).do()
+        self.assertEquals('def f(b, c, a):\n    pass\nf(2, 3, 1)\n',
+                          self.mod.read())
+
+    def test_resources_parameter(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('def a_func(param):\n    pass\n')
+        self.mod.write('import mod1\nmod1.a_func(1)\n')
+        signature = ChangeSignature(self.project, mod1,
+                                    mod1.read().index('a_func') + 1)
+        signature.get_changes([change_signature.ArgumentRemover(0)],
+                              resources=[mod1]).do()
+        self.assertEquals('import mod1\nmod1.a_func(1)\n', self.mod.read())
+        self.assertEquals('def a_func():\n    pass\n', mod1.read())
+
+    def test_reordering_and_automatic_defaults(self):
+        code = 'def f(p1, p2=2):\n' \
+               '    pass\n' \
+               'f(1, 2)\n'
+        self.mod.write(code)
+        signature = ChangeSignature(self.project, self.mod,
+                                    code.index('f('))
+        reorder = change_signature.ArgumentReorderer([1, 0], autodef='1')
+        signature.get_changes([reorder]).do()
+        expected = 'def f(p2=2, p1=1):\n' \
+                   '    pass\n' \
+                   'f(2, 1)\n'
+        self.assertEquals(expected, self.mod.read())
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/refactor/extracttest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,877 @@
+import unittest
+
+import rope.base.codeanalyze
+import rope.base.exceptions
+import ropetest.testutils as testutils
+from rope.refactor import extract
+from ropetest import testutils
+
+
+class ExtractMethodTest(unittest.TestCase):
+
+    def setUp(self):
+        super(ExtractMethodTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(ExtractMethodTest, self).tearDown()
+
+    def do_extract_method(self, source_code, start, end, extracted, **kwds):
+        testmod = testutils.create_module(self.project, 'testmod')
+        testmod.write(source_code)
+        extractor = extract.ExtractMethod(
+            self.project, testmod, start, end)
+        self.project.do(extractor.get_changes(extracted, **kwds))
+        return testmod.read()
+
+    def do_extract_variable(self, source_code, start, end, extracted, **kwds):
+        testmod = testutils.create_module(self.project, 'testmod')
+        testmod.write(source_code)
+        extractor = extract.ExtractVariable( self.project, testmod, start, end)
+        self.project.do(extractor.get_changes(extracted, **kwds))
+        return testmod.read()
+
+    def _convert_line_range_to_offset(self, code, start, end):
+        lines = rope.base.codeanalyze.SourceLinesAdapter(code)
+        return lines.get_line_start(start), lines.get_line_end(end)
+
+    def test_simple_extract_function(self):
+        code = "def a_func():\n    print('one')\n    print('two')\n"
+        start, end = self._convert_line_range_to_offset(code, 2, 2)
+        refactored = self.do_extract_method(code, start, end, 'extracted')
+        expected = "def a_func():\n    extracted()\n    print('two')\n\n" \
+                   "def extracted():\n    print('one')\n"
+        self.assertEquals(expected, refactored)
+
+    def test_extract_function_at_the_end_of_file(self):
+        code = "def a_func():\n    print('one')"
+        start, end = self._convert_line_range_to_offset(code, 2, 2)
+        refactored = self.do_extract_method(code, start, end, 'extracted')
+        expected = "def a_func():\n    extracted()\n" \
+                   "def extracted():\n    print('one')\n"
+        self.assertEquals(expected, refactored)
+
+    def test_extract_function_after_scope(self):
+        code = "def a_func():\n    print('one')\n    print('two')\n\nprint('hey')\n"
+        start, end = self._convert_line_range_to_offset(code, 2, 2)
+        refactored = self.do_extract_method(code, start, end, 'extracted')
+        expected = "def a_func():\n    extracted()\n    print('two')\n\n" \
+                   "def extracted():\n    print('one')\n\nprint('hey')\n"
+        self.assertEquals(expected, refactored)
+
+    def test_simple_extract_function_with_parameter(self):
+        code = "def a_func():\n    a_var = 10\n    print(a_var)\n"
+        start, end = self._convert_line_range_to_offset(code, 3, 3)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = "def a_func():\n    a_var = 10\n    new_func(a_var)\n\n" \
+                   "def new_func(a_var):\n    print(a_var)\n"
+        self.assertEquals(expected, refactored)
+
+    def test_not_unread_variables_as_parameter(self):
+        code = "def a_func():\n    a_var = 10\n    print('hey')\n"
+        start, end = self._convert_line_range_to_offset(code, 3, 3)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = "def a_func():\n    a_var = 10\n    new_func()\n\n" \
+                   "def new_func():\n    print('hey')\n"
+        self.assertEquals(expected, refactored)
+
+    def test_simple_extract_function_with_two_parameter(self):
+        code = 'def a_func():\n    a_var = 10\n    another_var = 20\n' \
+               '    third_var = a_var + another_var\n'
+        start, end = self._convert_line_range_to_offset(code, 4, 4)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'def a_func():\n    a_var = 10\n    another_var = 20\n' \
+                   '    new_func(a_var, another_var)\n\n' \
+                   'def new_func(a_var, another_var):\n' \
+                   '    third_var = a_var + another_var\n'
+        self.assertEquals(expected, refactored)
+
+    def test_simple_extract_function_with_return_value(self):
+        code = 'def a_func():\n    a_var = 10\n    print(a_var)\n'
+        start, end = self._convert_line_range_to_offset(code, 2, 2)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'def a_func():\n    a_var = new_func()\n    print(a_var)\n\n' \
+                   'def new_func():\n    a_var = 10\n    return a_var\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_function_with_multiple_return_values(self):
+        code = 'def a_func():\n    a_var = 10\n    another_var = 20\n' \
+               '    third_var = a_var + another_var\n'
+        start, end = self._convert_line_range_to_offset(code, 2, 3)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'def a_func():\n    a_var, another_var = new_func()\n' \
+                   '    third_var = a_var + another_var\n\n' \
+                   'def new_func():\n    a_var = 10\n    another_var = 20\n' \
+                   '    return a_var, another_var\n'
+        self.assertEquals(expected, refactored)
+
+    def test_simple_extract_method(self):
+        code = 'class AClass(object):\n\n' \
+               '    def a_func(self):\n        print(1)\n        print(2)\n'
+        start, end = self._convert_line_range_to_offset(code, 4, 4)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'class AClass(object):\n\n' \
+                   '    def a_func(self):\n' \
+                   '        self.new_func()\n' \
+                   '        print(2)\n\n' \
+                   '    def new_func(self):\n        print(1)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_method_with_args_and_returns(self):
+        code = 'class AClass(object):\n' \
+               '    def a_func(self):\n' \
+               '        a_var = 10\n' \
+               '        another_var = a_var * 3\n' \
+               '        third_var = a_var + another_var\n'
+        start, end = self._convert_line_range_to_offset(code, 4, 4)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'class AClass(object):\n' \
+                   '    def a_func(self):\n' \
+                   '        a_var = 10\n' \
+                   '        another_var = self.new_func(a_var)\n' \
+                   '        third_var = a_var + another_var\n\n' \
+                   '    def new_func(self, a_var):\n' \
+                   '        another_var = a_var * 3\n' \
+                   '        return another_var\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_method_with_self_as_argument(self):
+        code = 'class AClass(object):\n' \
+               '    def a_func(self):\n' \
+               '        print(self)\n'
+        start, end = self._convert_line_range_to_offset(code, 3, 3)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'class AClass(object):\n' \
+                   '    def a_func(self):\n' \
+                   '        self.new_func()\n\n' \
+                   '    def new_func(self):\n' \
+                   '        print(self)\n'
+        self.assertEquals(expected, refactored)
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_extract_method_with_no_self_as_argument(self):
+        code = 'class AClass(object):\n' \
+               '    def a_func():\n' \
+               '        print(1)\n'
+        start, end = self._convert_line_range_to_offset(code, 3, 3)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+
+    def test_extract_method_with_multiple_methods(self):
+        code = 'class AClass(object):\n' \
+               '    def a_func(self):\n' \
+               '        print(self)\n\n' \
+               '    def another_func(self):\n' \
+               '        pass\n'
+        start, end = self._convert_line_range_to_offset(code, 3, 3)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'class AClass(object):\n' \
+                   '    def a_func(self):\n' \
+                   '        self.new_func()\n\n' \
+                   '    def new_func(self):\n' \
+                   '        print(self)\n\n' \
+                   '    def another_func(self):\n' \
+                   '        pass\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_function_with_function_returns(self):
+        code = 'def a_func():\n    def inner_func():\n        pass\n' \
+               '    inner_func()\n'
+        start, end = self._convert_line_range_to_offset(code, 2, 3)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'def a_func():\n' \
+                   '    inner_func = new_func()\n    inner_func()\n\n' \
+                   'def new_func():\n' \
+                   '    def inner_func():\n        pass\n' \
+                   '    return inner_func\n'
+        self.assertEquals(expected, refactored)
+
+    def test_simple_extract_global_function(self):
+        code = "print('one')\nprint('two')\nprint('three')\n"
+        start, end = self._convert_line_range_to_offset(code, 2, 2)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = "print('one')\n\ndef new_func():\n    print('two')\n" \
+                   "\nnew_func()\nprint('three')\n"
+        self.assertEquals(expected, refactored)
+
+    def test_extract_global_function_inside_ifs(self):
+        code = 'if True:\n    a = 10\n'
+        start, end = self._convert_line_range_to_offset(code, 2, 2)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = '\ndef new_func():\n    a = 10\n\nif True:\n' \
+                   '    new_func()\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_function_while_inner_function_reads(self):
+        code = 'def a_func():\n    a_var = 10\n' \
+               '    def inner_func():\n        print(a_var)\n' \
+               '    return inner_func\n'
+        start, end = self._convert_line_range_to_offset(code, 3, 4)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'def a_func():\n    a_var = 10\n' \
+                   '    inner_func = new_func(a_var)\n    return inner_func\n\n' \
+                   'def new_func(a_var):\n' \
+                   '    def inner_func():\n        print(a_var)\n' \
+                   '    return inner_func\n'
+        self.assertEquals(expected, refactored)
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_extract_method_bad_range(self):
+        code = "def a_func():\n    pass\na_var = 10\n"
+        start, end = self._convert_line_range_to_offset(code, 2, 3)
+        self.do_extract_method(code, start, end, 'new_func')
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_extract_method_bad_range2(self):
+        code = "class AClass(object):\n    pass\n"
+        start, end = self._convert_line_range_to_offset(code, 1, 1)
+        self.do_extract_method(code, start, end, 'new_func')
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_extract_method_containing_return(self):
+        code = 'def a_func(arg):\n    if arg:\n        return arg * 2\n    return 1'
+        start, end = self._convert_line_range_to_offset(code, 2, 4)
+        self.do_extract_method(code, start, end, 'new_func')
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_extract_method_containing_yield(self):
+        code = "def a_func(arg):\n    yield arg * 2\n"
+        start, end = self._convert_line_range_to_offset(code, 2, 2)
+        self.do_extract_method(code, start, end, 'new_func')
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_extract_method_containing_uncomplete_lines(self):
+        code = 'a_var = 20\nanother_var = 30\n'
+        start = code.index('20')
+        end = code.index('30') + 2
+        self.do_extract_method(code, start, end, 'new_func')
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_extract_method_containing_uncomplete_lines2(self):
+        code = 'a_var = 20\nanother_var = 30\n'
+        start = code.index('20')
+        end = code.index('another') + 5
+        self.do_extract_method(code, start, end, 'new_func')
+
+    def test_extract_function_and_argument_as_paramenter(self):
+        code = 'def a_func(arg):\n    print(arg)\n'
+        start, end = self._convert_line_range_to_offset(code, 2, 2)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'def a_func(arg):\n    new_func(arg)\n\n' \
+                   'def new_func(arg):\n    print(arg)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_function_and_end_as_the_start_of_a_line(self):
+        code = 'print("hey")\nif True:\n    pass\n'
+        start = 0
+        end = code.index('\n') + 1
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = '\ndef new_func():\n    print("hey")\n\n' \
+                   'new_func()\nif True:\n    pass\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_function_and_indented_blocks(self):
+        code = 'def a_func(arg):\n    if True:\n' \
+               '        if True:\n            print(arg)\n'
+        start, end = self._convert_line_range_to_offset(code, 3, 4)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'def a_func(arg):\n    if True:\n        new_func(arg)\n\n' \
+                   'def new_func(arg):\n    if True:\n        print(arg)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_method_and_multi_line_headers(self):
+        code = 'def a_func(\n           arg):\n    print(arg)\n'
+        start, end = self._convert_line_range_to_offset(code, 3, 3)
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'def a_func(\n           arg):\n    new_func(arg)\n\n' \
+                   'def new_func(arg):\n    print(arg)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_single_line_extract_function(self):
+        code = 'a_var = 10 + 20\n'
+        start = code.index('10')
+        end = code.index('20') + 2
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = "\ndef new_func():\n    return 10 + 20\n\na_var = new_func()\n"
+        self.assertEquals(expected, refactored)
+
+    def test_single_line_extract_function2(self):
+        code = 'def a_func():\n    a = 10\n    b = a * 20\n'
+        start = code.rindex('a')
+        end = code.index('20') + 2
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'def a_func():\n    a = 10\n    b = new_func(a)\n' \
+                   '\ndef new_func(a):\n    return a * 20\n'
+        self.assertEquals(expected, refactored)
+
+    def test_single_line_extract_method_and_logical_lines(self):
+        code = 'a_var = 10 +\\\n    20\n'
+        start = code.index('10')
+        end = code.index('20') + 2
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = '\ndef new_func():\n    return 10 + 20\n\na_var = new_func()\n'
+        self.assertEquals(expected, refactored)
+
+    def test_single_line_extract_method_and_logical_lines2(self):
+        code = 'a_var = (10,\\\n    20)\n'
+        start = code.index('10') - 1
+        end = code.index('20') + 3
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = '\ndef new_func():\n' \
+                   '    return (10, 20)\n\na_var = new_func()\n'
+        self.assertEquals(expected, refactored)
+
+    def test_single_line_extract_method(self):
+        code = "class AClass(object):\n\n" \
+               "    def a_func(self):\n        a = 10\n        b = a * a\n"
+        start = code.rindex('=') + 2
+        end = code.rindex('a') + 1
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'class AClass(object):\n\n' \
+                   '    def a_func(self):\n' \
+                   '        a = 10\n        b = self.new_func(a)\n\n' \
+                   '    def new_func(self, a):\n        return a * a\n'
+        self.assertEquals(expected, refactored)
+
+    def test_single_line_extract_function_if_condition(self):
+        code = 'if True:\n    pass\n'
+        start = code.index('True')
+        end = code.index('True') + 4
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = "\ndef new_func():\n    return True\n\nif new_func():\n    pass\n"
+        self.assertEquals(expected, refactored)
+
+    def test_unneeded_params(self):
+        code = 'class A(object):\n    ' \
+               'def a_func(self):\n        a_var = 10\n        a_var += 2\n'
+        start = code.rindex('2')
+        end = code.rindex('2') + 1
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'class A(object):\n' \
+                   '    def a_func(self):\n        a_var = 10\n' \
+                   '        a_var += self.new_func()\n\n' \
+                   '    def new_func(self):\n        return 2\n'
+        self.assertEquals(expected, refactored)
+
+    def test_breaks_and_continues_inside_loops(self):
+        code = 'def a_func():\n    for i in range(10):\n        continue\n'
+        start = code.index('for')
+        end = len(code) - 1
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'def a_func():\n    new_func()\n\n' \
+                   'def new_func():\n' \
+                   '    for i in range(10):\n        continue\n'
+        self.assertEquals(expected, refactored)
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_breaks_and_continues_outside_loops(self):
+        code = 'def a_func():\n' \
+               '    for i in range(10):\n        a = i\n        continue\n'
+        start = code.index('a = i')
+        end = len(code) - 1
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+
+    def test_variable_writes_followed_by_variable_reads_after_extraction(self):
+        code = 'def a_func():\n    a = 1\n    a = 2\n    b = a\n'
+        start = code.index('a = 1')
+        end = code.index('a = 2') - 1
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'def a_func():\n    new_func()\n    a = 2\n    b = a\n\n' \
+                   'def new_func():\n    a = 1\n'
+        self.assertEquals(expected, refactored)
+
+    def test_variable_writes_followed_by_variable_reads_inside_extraction(self):
+        code = 'def a_func():\n    a = 1\n    a = 2\n    b = a\n'
+        start = code.index('a = 2')
+        end = len(code) - 1
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+        expected = 'def a_func():\n    a = 1\n    new_func()\n\n' \
+                   'def new_func():\n    a = 2\n    b = a\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_variable(self):
+        code = 'a_var = 10 + 20\n'
+        start = code.index('10')
+        end = code.index('20') + 2
+        refactored = self.do_extract_variable(code, start, end, 'new_var')
+        expected = 'new_var = 10 + 20\na_var = new_var\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_variable_multiple_lines(self):
+        code = 'a = 1\nb = 2\n'
+        start = code.index('1')
+        end = code.index('1') + 1
+        refactored = self.do_extract_variable(code, start, end, 'c')
+        expected = 'c = 1\na = c\nb = 2\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_variable_in_the_middle_of_statements(self):
+        code = 'a = 1 + 2\n'
+        start = code.index('1')
+        end = code.index('1') + 1
+        refactored = self.do_extract_variable(code, start, end, 'c')
+        expected = 'c = 1\na = c + 2\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_variable_for_a_tuple(self):
+        code = 'a = 1, 2\n'
+        start = code.index('1')
+        end = code.index('2') + 1
+        refactored = self.do_extract_variable(code, start, end, 'c')
+        expected = 'c = 1, 2\na = c\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_variable_for_a_string(self):
+        code = 'def a_func():\n    a = "hey!"\n'
+        start = code.index('"')
+        end = code.rindex('"') + 1
+        refactored = self.do_extract_variable(code, start, end, 'c')
+        expected = 'def a_func():\n    c = "hey!"\n    a = c\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_variable_inside_ifs(self):
+        code = 'if True:\n    a = 1 + 2\n'
+        start = code.index('1')
+        end = code.rindex('2') + 1
+        refactored = self.do_extract_variable(code, start, end, 'b')
+        expected = 'if True:\n    b = 1 + 2\n    a = b\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_variable_inside_ifs_and_logical_lines(self):
+        code = 'if True:\n    a = (3 + \n(1 + 2))\n'
+        start = code.index('1')
+        end = code.index('2') + 1
+        refactored = self.do_extract_variable(code, start, end, 'b')
+        expected = 'if True:\n    b = 1 + 2\n    a = (3 + \n(b))\n'
+        self.assertEquals(expected, refactored)
+
+    # TODO: Handle when extracting a subexpression
+    def xxx_test_extract_variable_for_a_subexpression(self):
+        code = 'a = 3 + 1 + 2\n'
+        start = code.index('1')
+        end = code.index('2') + 1
+        refactored = self.do_extract_variable(code, start, end, 'b')
+        expected = 'b = 1 + 2\na = 3 + b\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_variable_starting_from_the_start_of_the_line(self):
+        code = 'a_dict = {1: 1}\na_dict.values().count(1)\n'
+        start = code.rindex('a_dict')
+        end = code.index('count') - 1
+        refactored = self.do_extract_variable(code, start, end, 'values')
+        expected = 'a_dict = {1: 1}\nvalues = a_dict.values()\nvalues.count(1)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_variable_on_the_last_line_of_a_function(self):
+        code = 'def f():\n    a_var = {}\n    a_var.keys()\n'
+        start = code.rindex('a_var')
+        end = code.index('.keys')
+        refactored = self.do_extract_variable(code, start, end, 'new_var')
+        expected = 'def f():\n    a_var = {}\n    new_var = a_var\n    new_var.keys()\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_variable_on_the_indented_function_statement(self):
+        code = 'def f():\n    if True:\n        a_var = 1 + 2\n'
+        start = code.index('1')
+        end = code.index('2') + 1
+        refactored = self.do_extract_variable(code, start, end, 'new_var')
+        expected = 'def f():\n    if True:\n' \
+                   '        new_var = 1 + 2\n        a_var = new_var\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_method_on_the_last_line_of_a_function(self):
+        code = 'def f():\n    a_var = {}\n    a_var.keys()\n'
+        start = code.rindex('a_var')
+        end = code.index('.keys')
+        refactored = self.do_extract_method(code, start, end, 'new_f')
+        expected = 'def f():\n    a_var = {}\n    new_f(a_var).keys()\n\n' \
+                   'def new_f(a_var):\n    return a_var\n'
+        self.assertEquals(expected, refactored)
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_raising_exception_when_on_incomplete_variables(self):
+        code = 'a_var = 10 + 20\n'
+        start = code.index('10') + 1
+        end = code.index('20') + 2
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_raising_exception_when_on_incomplete_variables_on_end(self):
+        code = 'a_var = 10 + 20\n'
+        start = code.index('10')
+        end = code.index('20') + 1
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_raising_exception_on_bad_parens(self):
+        code = 'a_var = (10 + 20) + 30\n'
+        start = code.index('20')
+        end = code.index('30') + 2
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_raising_exception_on_bad_operators(self):
+        code = 'a_var = 10 + 20 + 30\n'
+        start = code.index('10')
+        end = code.rindex('+') + 1
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+
+    # FIXME: Extract method should be more intelligent about bad ranges
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def xxx_test_raising_exception_on_function_parens(self):
+        code = 'a = range(10)'
+        start = code.index('(')
+        end = code.rindex(')') + 1
+        refactored = self.do_extract_method(code, start, end, 'new_func')
+
+    def test_extract_method_and_extra_blank_lines(self):
+        code = '\nprint(1)\n'
+        refactored = self.do_extract_method(code, 0, len(code), 'new_f')
+        expected = '\n\ndef new_f():\n    print(1)\n\nnew_f()\n'
+        self.assertEquals(expected, refactored)
+
+    def test_variable_writes_in_the_same_line_as_variable_read(self):
+        code = 'a = 1\na = 1 + a\n'
+        start = code.index('\n') + 1
+        end = len(code)
+        refactored = self.do_extract_method(code, start, end, 'new_f',
+                                            global_=True)
+        expected = 'a = 1\n\ndef new_f(a):\n    a = 1 + a\n\nnew_f(a)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_variable_writes_in_the_same_line_as_variable_read2(self):
+        code = 'a = 1\na += 1\n'
+        start = code.index('\n') + 1
+        end = len(code)
+        refactored = self.do_extract_method(code, start, end, 'new_f',
+                                            global_=True)
+        expected = 'a = 1\n\ndef new_f():\n    a += 1\n\nnew_f()\n'
+        self.assertEquals(expected, refactored)
+
+    def test_variable_and_similar_expressions(self):
+        code = 'a = 1\nb = 1\n'
+        start = code.index('1')
+        end = start + 1
+        refactored = self.do_extract_variable(code, start, end,
+                                              'one', similar=True)
+        expected = 'one = 1\na = one\nb = one\n'
+        self.assertEquals(expected, refactored)
+
+    def test_definition_should_appear_before_the_first_use(self):
+        code = 'a = 1\nb = 1\n'
+        start = code.rindex('1')
+        end = start + 1
+        refactored = self.do_extract_variable(code, start, end,
+                                              'one', similar=True)
+        expected = 'one = 1\na = one\nb = one\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_method_and_similar_expressions(self):
+        code = 'a = 1\nb = 1\n'
+        start = code.index('1')
+        end = start + 1
+        refactored = self.do_extract_method(code, start, end,
+                                            'one', similar=True)
+        expected = '\ndef one():\n    return 1\n\na = one()\nb = one()\n'
+        self.assertEquals(expected, refactored)
+
+    def test_simple_extract_method_and_similar_statements(self):
+        code = 'class AClass(object):\n\n' \
+               '    def func1(self):\n        a = 1 + 2\n        b = a\n' \
+               '    def func2(self):\n        a = 1 + 2\n        b = a\n'
+        start, end = self._convert_line_range_to_offset(code, 4, 4)
+        refactored = self.do_extract_method(code, start, end,
+                                            'new_func', similar=True)
+        expected = 'class AClass(object):\n\n' \
+                   '    def func1(self):\n' \
+                   '        a = self.new_func()\n        b = a\n\n' \
+                   '    def new_func(self):\n' \
+                   '        a = 1 + 2\n        return a\n' \
+                   '    def func2(self):\n' \
+                   '        a = self.new_func()\n        b = a\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_method_and_similar_statements2(self):
+        code = 'class AClass(object):\n\n' \
+               '    def func1(self, p1):\n        a = p1 + 2\n' \
+               '    def func2(self, p2):\n        a = p2 + 2\n'
+        start = code.rindex('p1')
+        end =  code.index('2\n') + 1
+        refactored = self.do_extract_method(code, start, end,
+                                            'new_func', similar=True)
+        expected = 'class AClass(object):\n\n' \
+                   '    def func1(self, p1):\n        a = self.new_func(p1)\n\n' \
+                   '    def new_func(self, p1):\n        return p1 + 2\n' \
+                   '    def func2(self, p2):\n        a = self.new_func(p2)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_method_and_similar_statements_where_return_is_different(self):
+        code = 'class AClass(object):\n\n' \
+               '    def func1(self, p1):\n        a = p1 + 2\n' \
+               '    def func2(self, p2):\n        self.attr = p2 + 2\n'
+        start = code.rindex('p1')
+        end =  code.index('2\n') + 1
+        refactored = self.do_extract_method(code, start, end,
+                                            'new_func', similar=True)
+        expected = 'class AClass(object):\n\n' \
+                   '    def func1(self, p1):\n        a = self.new_func(p1)\n\n' \
+                   '    def new_func(self, p1):\n        return p1 + 2\n' \
+                   '    def func2(self, p2):\n        self.attr = self.new_func(p2)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_definition_should_appear_where_it_is_visible(self):
+        code = 'if True:\n    a = 1\nelse:\n    b = 1\n'
+        start = code.rindex('1')
+        end = start + 1
+        refactored = self.do_extract_variable(code, start, end,
+                                              'one', similar=True)
+        expected = 'one = 1\nif True:\n    a = one\nelse:\n    b = one\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_variable_and_similar_statements_in_classes(self):
+        code = 'class AClass(object):\n\n' \
+               '    def func1(self):\n        a = 1\n' \
+               '    def func2(self):\n        b = 1\n'
+        start = code.index(' 1') + 1
+        refactored = self.do_extract_variable(code, start, start + 1,
+                                              'one', similar=True)
+        expected = 'class AClass(object):\n\n' \
+                   '    def func1(self):\n        one = 1\n        a = one\n' \
+                   '    def func2(self):\n        b = 1\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_method_in_staticmethods(self):
+        code = 'class AClass(object):\n\n' \
+               '    @staticmethod\n    def func2():\n        b = 1\n'
+        start = code.index(' 1') + 1
+        refactored = self.do_extract_method(code, start, start + 1,
+                                            'one', similar=True)
+        expected = 'class AClass(object):\n\n' \
+                   '    @staticmethod\n    def func2():\n' \
+                   '        b = AClass.one()\n\n' \
+                   '    @staticmethod\n    def one():\n' \
+                   '        return 1\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_normal_method_with_staticmethods(self):
+        code = 'class AClass(object):\n\n' \
+               '    @staticmethod\n    def func1():\n        b = 1\n' \
+               '    def func2(self):\n        b = 1\n'
+        start = code.rindex(' 1') + 1
+        refactored = self.do_extract_method(code, start, start + 1,
+                                            'one', similar=True)
+        expected = 'class AClass(object):\n\n' \
+                   '    @staticmethod\n    def func1():\n        b = 1\n' \
+                   '    def func2(self):\n        b = self.one()\n\n' \
+                   '    def one(self):\n        return 1\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_variable_with_no_new_lines_at_the_end(self):
+        code = 'a_var = 10'
+        start = code.index('10')
+        end = start + 2
+        refactored = self.do_extract_variable(code, start, end, 'new_var')
+        expected = 'new_var = 10\na_var = new_var'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_method_containing_return_in_functions(self):
+        code = 'def f(arg):\n    return arg\nprint(f(1))\n'
+        start, end = self._convert_line_range_to_offset(code, 1, 3)
+        refactored = self.do_extract_method(code, start, end, 'a_func')
+        expected = '\ndef a_func():\n    def f(arg):\n        return arg\n' \
+                   '    print(f(1))\n\na_func()\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_method_and_varying_first_parameter(self):
+        code = 'class C(object):\n' \
+               '    def f1(self):\n        print(str(self))\n' \
+               '    def f2(self):\n        print(str(1))\n'
+        start = code.index('print(') + 6
+        end = code.index('))\n') + 1
+        refactored = self.do_extract_method(code, start, end,
+                                            'to_str', similar=True)
+        expected = 'class C(object):\n' \
+                   '    def f1(self):\n        print(self.to_str())\n\n' \
+                   '    def to_str(self):\n        return str(self)\n' \
+                   '    def f2(self):\n        print(str(1))\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_method_when_an_attribute_exists_in_function_scope(self):
+        code = 'class A(object):\n    def func(self):\n        pass\n' \
+               'a = A()\n' \
+               'def f():\n' \
+               '    func = a.func()\n' \
+               '    print func\n'
+
+        start, end = self._convert_line_range_to_offset(code, 6, 6)
+        refactored = self.do_extract_method(code, start, end, 'g')
+        refactored = refactored[refactored.index('A()') + 4:]
+        expected = 'def f():\n    func = g()\n    print func\n\n' \
+                   'def g():\n    func = a.func()\n    return func\n'
+        self.assertEquals(expected, refactored)
+
+    def test_global_option_for_extract_method(self):
+        code = 'def a_func():\n    print(1)\n'
+        start, end = self._convert_line_range_to_offset(code, 2, 2)
+        refactored = self.do_extract_method(code, start, end,
+                                            'extracted', global_=True)
+        expected = 'def a_func():\n    extracted()\n\n' \
+                   'def extracted():\n    print(1)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_global_extract_method(self):
+        code = 'class AClass(object):\n\n' \
+               '    def a_func(self):\n        print(1)\n'
+        start, end = self._convert_line_range_to_offset(code, 4, 4)
+        refactored = self.do_extract_method(code, start, end,
+                                            'new_func', global_=True)
+        expected = 'class AClass(object):\n\n' \
+                   '    def a_func(self):\n        new_func()\n\n' \
+                   'def new_func():\n    print(1)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_method_with_multiple_methods(self):
+        code = 'class AClass(object):\n' \
+               '    def a_func(self):\n' \
+               '        print(1)\n\n' \
+               '    def another_func(self):\n' \
+               '        pass\n'
+        start, end = self._convert_line_range_to_offset(code, 3, 3)
+        refactored = self.do_extract_method(code, start, end,
+                                            'new_func', global_=True)
+        expected = 'class AClass(object):\n' \
+                   '    def a_func(self):\n' \
+                   '        new_func()\n\n' \
+                   '    def another_func(self):\n' \
+                   '        pass\n\n' \
+                   'def new_func():\n' \
+                   '    print(1)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_where_to_seach_when_extracting_global_names(self):
+        code = 'def a():\n    return 1\ndef b():\n    return 1\nb = 1\n'
+        start = code.index('1')
+        end = start + 1
+        refactored = self.do_extract_variable(code, start, end, 'one',
+                                              similar=True, global_=True)
+        expected = 'def a():\n    return one\none = 1\n' \
+            'def b():\n    return one\nb = one\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extracting_pieces_with_distinct_temp_names(self):
+        code = 'a = 1\nprint a\nb = 1\nprint b\n'
+        start = code.index('a')
+        end = code.index('\nb')
+        refactored = self.do_extract_method(code, start, end, 'f',
+                                            similar=True, global_=True)
+        expected = '\ndef f():\n    a = 1\n    print a\n\nf()\nf()\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extracting_methods_in_global_functions_should_be_global(self):
+        code = 'def f():\n    a = 1\ndef g():\n    b = 1\n'
+        start = code.rindex('1')
+        refactored = self.do_extract_method(code, start, start + 1, 'one',
+                                            similar=True, global_=False)
+        expected = 'def f():\n    a = one()\ndef g():\n    b = one()\n\n' \
+                   'def one():\n    return 1\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extracting_methods_in_global_functions_should_be_global(self):
+        code = 'if 1:\n    var = 2\n'
+        start = code.rindex('2')
+        refactored = self.do_extract_method(code, start, start + 1, 'two',
+                                            similar=True, global_=False)
+        expected = '\ndef two():\n    return 2\n\nif 1:\n    var = two()\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_method_and_try_blocks(self):
+        code = 'def f():\n    try:\n        pass\n' \
+               '    except Exception:\n        pass\n'
+        start, end = self._convert_line_range_to_offset(code, 2, 5)
+        refactored = self.do_extract_method(code, start, end, 'g')
+        expected = 'def f():\n    g()\n\ndef g():\n    try:\n        pass\n' \
+                   '    except Exception:\n        pass\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_and_not_passing_global_functions(self):
+        code = 'def next(p):\n    return p + 1\nvar = next(1)\n'
+        start = code.rindex('next')
+        refactored = self.do_extract_method(code, start, len(code) - 1, 'two')
+        expected = 'def next(p):\n    return p + 1\n' \
+                   '\ndef two():\n    return next(1)\n\nvar = two()\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extracting_with_only_one_return(self):
+        code = 'def f():\n    var = 1\n    return var\n'
+        start, end = self._convert_line_range_to_offset(code, 2, 3)
+        refactored = self.do_extract_method(code, start, end, 'g')
+        expected = 'def f():\n    return g()\n\n' \
+                   'def g():\n    var = 1\n    return var\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extracting_variable_and_implicit_continuations(self):
+        code = 's = ("1"\n  "2")\n'
+        start = code.index('"')
+        end = code.rindex('"') + 1
+        refactored = self.do_extract_variable(code, start, end, 's2')
+        expected = 's2 = "1" "2"\ns = (s2)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extracting_method_and_implicit_continuations(self):
+        code = 's = ("1"\n  "2")\n'
+        start = code.index('"')
+        end = code.rindex('"') + 1
+        refactored = self.do_extract_method(code, start, end, 'f')
+        expected = '\ndef f():\n    return "1" "2"\n\ns = (f())\n'
+        self.assertEquals(expected, refactored)
+
+    def test_passing_conditional_updated_vars_in_extracted(self):
+        code = 'def f(a):\n' \
+               '    if 0:\n' \
+               '        a = 1\n' \
+               '    print(a)\n'
+        start, end = self._convert_line_range_to_offset(code, 2, 4)
+        refactored = self.do_extract_method(code, start, end, 'g')
+        expected = 'def f(a):\n' \
+                   '    g(a)\n\n' \
+                   'def g(a):\n' \
+                   '    if 0:\n' \
+                   '        a = 1\n' \
+                   '    print(a)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_returning_conditional_updated_vars_in_extracted(self):
+        code = 'def f(a):\n' \
+               '    if 0:\n' \
+               '        a = 1\n' \
+               '    print(a)\n'
+        start, end = self._convert_line_range_to_offset(code, 2, 3)
+        refactored = self.do_extract_method(code, start, end, 'g')
+        expected = 'def f(a):\n' \
+                   '    a = g(a)\n' \
+                   '    print(a)\n\n' \
+                   'def g(a):\n' \
+                   '    if 0:\n' \
+                   '        a = 1\n' \
+                   '    return a\n'
+        self.assertEquals(expected, refactored)
+
+    def test_extract_method_with_variables_possibly_written_to(self):
+        code = "def a_func(b):\n" \
+               "    if b > 0:\n" \
+               "        a = 2\n" \
+               "    print a\n"
+        start, end = self._convert_line_range_to_offset(code, 2, 3)
+        refactored = self.do_extract_method(code, start, end, 'extracted')
+        expected = "def a_func(b):\n" \
+                   "    a = extracted(b)\n" \
+                   "    print a\n\n" \
+                   "def extracted(b):\n" \
+                   "    if b > 0:\n" \
+                   "        a = 2\n" \
+                   "    return a\n"
+        self.assertEquals(expected, refactored)
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/refactor/importutilstest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,990 @@
+import unittest
+
+from rope.refactor.importutils import ImportTools, importinfo, add_import
+from ropetest import testutils
+
+
+class ImportUtilsTest(unittest.TestCase):
+
+    def setUp(self):
+        super(ImportUtilsTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+        self.import_tools = ImportTools(self.pycore)
+
+        self.mod = testutils.create_module(self.project, 'mod')
+        self.pkg1 = testutils.create_package(self.project, 'pkg1')
+        self.mod1 = testutils.create_module(self.project, 'mod1', self.pkg1)
+        self.pkg2 = testutils.create_package(self.project, 'pkg2')
+        self.mod2 = testutils.create_module(self.project, 'mod2', self.pkg2)
+        self.mod3 = testutils.create_module(self.project, 'mod3', self.pkg2)
+        p1 = testutils.create_package(self.project, 'p1')
+        p2 = testutils.create_package(self.project, 'p2', p1)
+        p3 = testutils.create_package(self.project, 'p3', p2)
+        m1 = testutils.create_module(self.project, 'm1', p3)
+        l = testutils.create_module(self.project, 'l', p3)
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(ImportUtilsTest, self).tearDown()
+
+    def test_get_import_for_module(self):
+        mod = self.pycore.find_module('mod')
+        import_statement = self.import_tools.get_import(mod)
+        self.assertEquals('import mod', import_statement.get_import_statement())
+
+    def test_get_import_for_module_in_nested_modules(self):
+        mod = self.pycore.find_module('pkg1.mod1')
+        import_statement = self.import_tools.get_import(mod)
+        self.assertEquals('import pkg1.mod1', import_statement.get_import_statement())
+
+    def test_get_import_for_module_in_init_dot_py(self):
+        init_dot_py = self.pkg1.get_child('__init__.py')
+        import_statement = self.import_tools.get_import(init_dot_py)
+        self.assertEquals('import pkg1', import_statement.get_import_statement())
+
+
+    def test_get_from_import_for_module(self):
+        mod = self.pycore.find_module('mod')
+        import_statement = self.import_tools.get_from_import(mod, 'a_func')
+        self.assertEquals('from mod import a_func',
+                          import_statement.get_import_statement())
+
+    def test_get_from_import_for_module_in_nested_modules(self):
+        mod = self.pycore.find_module('pkg1.mod1')
+        import_statement = self.import_tools.get_from_import(mod, 'a_func')
+        self.assertEquals('from pkg1.mod1 import a_func',
+                          import_statement.get_import_statement())
+
+    def test_get_from_import_for_module_in_init_dot_py(self):
+        init_dot_py = self.pkg1.get_child('__init__.py')
+        import_statement = self.import_tools.\
+                           get_from_import(init_dot_py, 'a_func')
+        self.assertEquals('from pkg1 import a_func',
+                          import_statement.get_import_statement())
+
+
+    def test_get_import_statements(self):
+        self.mod.write('import pkg1\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.imports
+        self.assertEquals('import pkg1',
+                          imports[0].import_info.get_import_statement())
+
+    def test_get_import_statements_with_alias(self):
+        self.mod.write('import pkg1.mod1 as mod1\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.imports
+        self.assertEquals('import pkg1.mod1 as mod1',
+                          imports[0].import_info.get_import_statement())
+
+    def test_get_import_statements_for_froms(self):
+        self.mod.write('from pkg1 import mod1\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.imports
+        self.assertEquals('from pkg1 import mod1',
+                          imports[0].import_info.get_import_statement())
+
+    def test_get_multi_line_import_statements_for_froms(self):
+        self.mod.write('from pkg1 \\\n    import mod1\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.imports
+        self.assertEquals('from pkg1 import mod1',
+                          imports[0].import_info.get_import_statement())
+
+    def test_get_import_statements_for_from_star(self):
+        self.mod.write('from pkg1 import *\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.imports
+        self.assertEquals('from pkg1 import *',
+                          imports[0].import_info.get_import_statement())
+
+    @testutils.run_only_for_25
+    def test_get_import_statements_for_new_relatives(self):
+        self.mod2.write('from .mod3 import x\n')
+        pymod = self.pycore.get_module('pkg2.mod2')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.imports
+        self.assertEquals('from .mod3 import x',
+                          imports[0].import_info.get_import_statement())
+
+    def test_ignoring_indented_imports(self):
+        self.mod.write('if True:\n    import pkg1\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.imports
+        self.assertEquals(0, len(imports))
+
+    def test_import_get_names(self):
+        self.mod.write('import pkg1 as pkg\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.imports
+        context = importinfo.ImportContext(self.pycore, self.project.root)
+        self.assertEquals(['pkg'],
+                          imports[0].import_info.get_imported_names(context))
+
+    def test_import_get_names_with_alias(self):
+        self.mod.write('import pkg1.mod1\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.imports
+        context = importinfo.ImportContext(self.pycore, self.project.root)
+        self.assertEquals(['pkg1'],
+                          imports[0].import_info.get_imported_names(context))
+
+    def test_import_get_names_with_alias2(self):
+        self.mod1.write('def a_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import *\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.imports
+        context = importinfo.ImportContext(self.pycore, self.project.root)
+        self.assertEquals(['a_func'],
+                          imports[0].import_info.get_imported_names(context))
+
+    def test_empty_getting_used_imports(self):
+        self.mod.write('')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.get_used_imports(pymod)
+        self.assertEquals(0, len(imports))
+
+    def test_empty_getting_used_imports2(self):
+        self.mod.write('import pkg\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.get_used_imports(pymod)
+        self.assertEquals(0, len(imports))
+
+    def test_simple_getting_used_imports(self):
+        self.mod.write('import pkg\nprint(pkg)\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.get_used_imports(pymod)
+        self.assertEquals(1, len(imports))
+        self.assertEquals('import pkg', imports[0].get_import_statement())
+
+    def test_simple_getting_used_imports2(self):
+        self.mod.write('import pkg\ndef a_func():\n    print(pkg)\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.get_used_imports(pymod)
+        self.assertEquals(1, len(imports))
+        self.assertEquals('import pkg', imports[0].get_import_statement())
+
+    def test_getting_used_imports_for_nested_scopes(self):
+        self.mod.write('import pkg1\nprint(pkg1)\ndef a_func():\n    pass\nprint(pkg1)\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.get_used_imports(
+            pymod['a_func'].get_object())
+        self.assertEquals(0, len(imports))
+
+    def test_getting_used_imports_for_nested_scopes2(self):
+        self.mod.write('from pkg1 import mod1\ndef a_func():\n    print(mod1)\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.get_used_imports(
+            pymod['a_func'].get_object())
+        self.assertEquals(1, len(imports))
+        self.assertEquals('from pkg1 import mod1', imports[0].get_import_statement())
+
+    def test_empty_removing_unused_imports(self):
+        self.mod.write('import pkg1\nprint(pkg1)\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('import pkg1\nprint(pkg1)\n',
+                          module_with_imports.get_changed_source())
+
+    def test_simple_removing_unused_imports(self):
+        self.mod.write('import pkg1\n\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('', module_with_imports.get_changed_source())
+
+    def test_simple_removing_unused_imports_for_froms(self):
+        self.mod1.write('def a_func():\n    pass\ndef another_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import a_func, another_func\n\na_func()\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('from pkg1.mod1 import a_func\n\na_func()\n',
+                          module_with_imports.get_changed_source())
+
+    def test_simple_removing_unused_imports_for_from_stars(self):
+        self.mod.write('from pkg1.mod1 import *\n\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('', module_with_imports.get_changed_source())
+
+    def test_simple_removing_unused_imports_for_nested_modules(self):
+        self.mod1.write('def a_func():\n    pass\n')
+        self.mod.write('import pkg1.mod1\npkg1.mod1.a_func()')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('import pkg1.mod1\npkg1.mod1.a_func()',
+                          module_with_imports.get_changed_source())
+
+    def test_removing_unused_imports_and_functions_of_the_same_name(self):
+        self.mod.write('def a_func():\n    pass\ndef a_func():\n    pass\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('def a_func():\n    pass\ndef a_func():\n    pass\n',
+                          module_with_imports.get_changed_source())
+
+    def test_removing_unused_imports_for_from_import_with_as(self):
+        self.mod.write('a_var = 1\n')
+        self.mod1.write('from mod import a_var as myvar\na_var = myvar\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod1)
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('from mod import a_var as myvar\na_var = myvar\n',
+                          module_with_imports.get_changed_source())
+
+    def test_not_removing_imports_that_conflict_with_class_names(self):
+        code = 'import pkg1\nclass A(object):\n    pkg1 = 0\n' \
+               '    def f(self):\n        a_var = pkg1\n'
+        self.mod.write(code)
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals(code, module_with_imports.get_changed_source())
+
+    def test_adding_imports(self):
+        self.mod.write('\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        new_import = self.import_tools.get_import(self.mod1)
+        module_with_imports.add_import(new_import)
+        self.assertEquals('import pkg1.mod1\n',
+                          module_with_imports.get_changed_source())
+
+    def test_adding_from_imports(self):
+        self.mod1.write('def a_func():\n    pass\ndef another_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import a_func\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        new_import = self.import_tools.get_from_import(
+            self.mod1, 'another_func')
+        module_with_imports.add_import(new_import)
+        self.assertEquals('from pkg1.mod1 import a_func, another_func\n',
+                          module_with_imports.get_changed_source())
+
+    def test_adding_to_star_imports(self):
+        self.mod1.write('def a_func():\n    pass\ndef another_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import *\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        new_import = self.import_tools.get_from_import(
+            self.mod1, 'another_func')
+        module_with_imports.add_import(new_import)
+        self.assertEquals('from pkg1.mod1 import *\n',
+                          module_with_imports.get_changed_source())
+
+    def test_adding_star_imports(self):
+        self.mod1.write('def a_func():\n    pass\ndef another_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import a_func\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        new_import = self.import_tools.get_from_import(self.mod1,
+                                                                  '*')
+        module_with_imports.add_import(new_import)
+        self.assertEquals('from pkg1.mod1 import *\n',
+                          module_with_imports.get_changed_source())
+
+    def test_adding_imports_and_preserving_spaces_after_imports(self):
+        self.mod.write('import pkg1\n\n\nprint(pkg1)\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        new_import = self.import_tools.get_import(self.pkg2)
+        module_with_imports.add_import(new_import)
+        self.assertEquals('import pkg1\nimport pkg2\n\n\nprint(pkg1)\n',
+                          module_with_imports.get_changed_source())
+
+    def test_not_changing_the_format_of_unchanged_imports(self):
+        self.mod1.write('def a_func():\n    pass\ndef another_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import (a_func,\n    another_func)\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        self.assertEquals(
+            'from pkg1.mod1 import (a_func,\n    another_func)\n',
+            module_with_imports.get_changed_source())
+
+    def test_not_changing_the_format_of_unchanged_imports2(self):
+        self.mod1.write('def a_func():\n    pass\ndef another_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import (a_func)\na_func()\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('from pkg1.mod1 import (a_func)\na_func()\n',
+                          module_with_imports.get_changed_source())
+
+    def test_removing_unused_imports_and_reoccuring_names(self):
+        self.mod1.write('def a_func():\n    pass\n'
+                        'def another_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import *\n'
+                       'from pkg1.mod1 import a_func\na_func()\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('from pkg1.mod1 import *\na_func()\n',
+                          module_with_imports.get_changed_source())
+
+    def test_removing_unused_imports_and_reoccuring_names2(self):
+        self.mod.write('import pkg2.mod2\nimport pkg2.mod3\n'
+                       'print(pkg2.mod2, pkg2.mod3)')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals(
+            'import pkg2.mod2\nimport pkg2.mod3\nprint(pkg2.mod2, pkg2.mod3)',
+            module_with_imports.get_changed_source())
+
+    def test_removing_unused_imports_and_common_packages(self):
+        self.mod.write('import pkg1.mod1\nimport pkg1\nprint(pkg1, pkg1.mod1)\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('import pkg1.mod1\nprint(pkg1, pkg1.mod1)\n',
+                          module_with_imports.get_changed_source())
+
+    def test_removing_unused_imports_and_common_packages_reversed(self):
+        self.mod.write('import pkg1\nimport pkg1.mod1\nprint(pkg1, pkg1.mod1)\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_duplicates()
+        self.assertEquals('import pkg1.mod1\nprint(pkg1, pkg1.mod1)\n',
+                          module_with_imports.get_changed_source())
+
+    def test_removing_unused_imports_and_common_packages2(self):
+        self.mod.write('import pkg1.mod1\nimport pkg1.mod2\nprint(pkg1)\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('import pkg1.mod1\nprint(pkg1)\n',
+                          module_with_imports.get_changed_source())
+
+    def test_removing_unused_imports_and_froms(self):
+        self.mod1.write('def func1():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import func1\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('', module_with_imports.get_changed_source())
+
+    def test_removing_unused_imports_and_froms2(self):
+        self.mod1.write('def func1():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import func1\nfunc1()')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('from pkg1.mod1 import func1\nfunc1()',
+                          module_with_imports.get_changed_source())
+
+    def test_removing_unused_imports_and_froms3(self):
+        self.mod1.write('def func1():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import func1\n'
+                       'def a_func():\n    func1()\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals(
+            'from pkg1.mod1 import func1\ndef a_func():\n    func1()\n',
+            module_with_imports.get_changed_source())
+
+    def test_removing_unused_imports_and_froms4(self):
+        self.mod1.write('def func1():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import func1\nclass A(object):\n'
+                       '    def a_func(self):\n        func1()\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('from pkg1.mod1 import func1\nclass A(object):\n'
+                          '    def a_func(self):\n        func1()\n',
+                          module_with_imports.get_changed_source())
+
+    def test_removing_unused_imports_and_getting_attributes(self):
+        self.mod1.write('class A(object):\n    def f(self):\n        pass\n')
+        self.mod.write('from pkg1.mod1 import A\nvar = A().f()')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('from pkg1.mod1 import A\nvar = A().f()',
+                          module_with_imports.get_changed_source())
+
+    def test_removing_unused_imports_function_parameters(self):
+        self.mod1.write('def func1():\n    pass\n')
+        self.mod.write('import pkg1\ndef a_func(pkg1):\n    my_var = pkg1\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('def a_func(pkg1):\n    my_var = pkg1\n',
+                          module_with_imports.get_changed_source())
+
+    def test_trivial_expanding_star_imports(self):
+        self.mod1.write('def a_func():\n    pass\ndef another_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import *\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.expand_stars()
+        self.assertEquals('', module_with_imports.get_changed_source())
+
+    def test_expanding_star_imports(self):
+        self.mod1.write('def a_func():\n    pass\ndef another_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import *\na_func()\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.expand_stars()
+        self.assertEquals('from pkg1.mod1 import a_func\na_func()\n',
+                          module_with_imports.get_changed_source())
+
+    def test_removing_duplicate_imports(self):
+        self.mod.write('import pkg1\nimport pkg1\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_duplicates()
+        self.assertEquals('import pkg1\n',
+                          module_with_imports.get_changed_source())
+
+    def test_removing_duplicates_and_reoccuring_names(self):
+        self.mod.write('import pkg2.mod2\nimport pkg2.mod3\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_duplicates()
+        self.assertEquals('import pkg2.mod2\nimport pkg2.mod3\n',
+                          module_with_imports.get_changed_source())
+
+    def test_removing_duplicate_imports_for_froms(self):
+        self.mod1.write(
+            'def a_func():\n    pass\ndef another_func():\n    pass\n')
+        self.mod.write('from pkg1 import a_func\n'
+                       'from pkg1 import a_func, another_func\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_duplicates()
+        self.assertEquals('from pkg1 import a_func, another_func\n',
+                          module_with_imports.get_changed_source())
+
+    def test_transforming_froms_to_normal_changing_imports(self):
+        self.mod1.write('def a_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import a_func\nprint(a_func)\n')
+        pymod = self.pycore.get_module('mod')
+        changed_module = self.import_tools.froms_to_imports(pymod)
+        self.assertEquals('import pkg1.mod1\nprint(pkg1.mod1.a_func)\n',
+                          changed_module)
+
+    def test_transforming_froms_to_normal_changing_occurances(self):
+        self.mod1.write('def a_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import a_func\na_func()')
+        pymod = self.pycore.get_module('mod')
+        changed_module = self.import_tools.froms_to_imports(pymod)
+        self.assertEquals('import pkg1.mod1\npkg1.mod1.a_func()',
+                          changed_module)
+
+    def test_transforming_froms_to_normal_for_multi_imports(self):
+        self.mod1.write('def a_func():\n    pass\ndef another_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import *\na_func()\nanother_func()\n')
+        pymod = self.pycore.get_module('mod')
+        changed_module = self.import_tools.froms_to_imports(pymod)
+        self.assertEquals(
+            'import pkg1.mod1\npkg1.mod1.a_func()\npkg1.mod1.another_func()\n',
+            changed_module)
+
+    def test_transforming_froms_to_normal_for_multi_imports_inside_parens(self):
+        self.mod1.write('def a_func():\n    pass\ndef another_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import (a_func, \n    another_func)' \
+                       '\na_func()\nanother_func()\n')
+        pymod = self.pycore.get_module('mod')
+        changed_module = self.import_tools.froms_to_imports(pymod)
+        self.assertEquals(
+            'import pkg1.mod1\npkg1.mod1.a_func()\npkg1.mod1.another_func()\n',
+            changed_module)
+
+    def test_transforming_froms_to_normal_from_stars(self):
+        self.mod1.write('def a_func():\n    pass\n')
+        self.mod.write('from pkg1.mod1 import *\na_func()\n')
+        pymod = self.pycore.get_module('mod')
+        changed_module = self.import_tools.froms_to_imports(pymod)
+        self.assertEquals('import pkg1.mod1\npkg1.mod1.a_func()\n', changed_module)
+
+    def test_transforming_froms_to_normal_from_stars2(self):
+        self.mod1.write('a_var = 10')
+        self.mod.write('import pkg1.mod1\nfrom pkg1.mod1 import a_var\n' \
+                       'def a_func():\n    print(pkg1.mod1, a_var)\n')
+        pymod = self.pycore.get_module('mod')
+        changed_module = self.import_tools.froms_to_imports(pymod)
+        self.assertEquals('import pkg1.mod1\n' \
+                          'def a_func():\n    print(pkg1.mod1, pkg1.mod1.a_var)\n',
+                          changed_module)
+
+    def test_transforming_froms_to_normal_from_with_alias(self):
+        self.mod1.write('def a_func():\n    pass\n')
+        self.mod.write(
+            'from pkg1.mod1 import a_func as another_func\nanother_func()\n')
+        pymod = self.pycore.get_module('mod')
+        changed_module = self.import_tools.froms_to_imports(pymod)
+        self.assertEquals('import pkg1.mod1\npkg1.mod1.a_func()\n',
+                          changed_module)
+
+    def test_transforming_froms_to_normal_for_relatives(self):
+        self.mod2.write('def a_func():\n    pass\n')
+        self.mod3.write('from mod2 import *\na_func()\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod3)
+        changed_module = self.import_tools.froms_to_imports(pymod)
+        self.assertEquals('import pkg2.mod2\npkg2.mod2.a_func()\n',
+                          changed_module)
+
+    def test_transforming_froms_to_normal_for_os_path(self):
+        self.mod.write('from os import path\npath.exists(\'.\')\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        changed_module = self.import_tools.froms_to_imports(pymod)
+        self.assertEquals('import os\nos.path.exists(\'.\')\n', changed_module)
+
+    def test_transform_relatives_imports_to_absolute_imports_doing_nothing(self):
+        self.mod2.write('from pkg1 import mod1\nimport mod1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod2)
+        self.assertEquals('from pkg1 import mod1\nimport mod1\n',
+                          self.import_tools.relatives_to_absolutes(pymod))
+
+    def test_transform_relatives_to_absolute_imports_for_normal_imports(self):
+        self.mod2.write('import mod3\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod2)
+        self.assertEquals('import pkg2.mod3\n',
+                          self.import_tools.relatives_to_absolutes(pymod))
+
+    def test_transform_relatives_imports_to_absolute_imports_for_froms(self):
+        self.mod3.write('def a_func():\n    pass\n')
+        self.mod2.write('from mod3 import a_func\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod2)
+        self.assertEquals('from pkg2.mod3 import a_func\n',
+                          self.import_tools.relatives_to_absolutes(pymod))
+
+    @testutils.run_only_for_25
+    def test_transform_relatives_imports_to_absolute_imports_for_new_relatives(self):
+        self.mod3.write('def a_func():\n    pass\n')
+        self.mod2.write('from .mod3 import a_func\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod2)
+        self.assertEquals('from pkg2.mod3 import a_func\n',
+                          self.import_tools.relatives_to_absolutes(pymod))
+
+    def test_transform_relatives_to_absolute_imports_for_normal_imports2(self):
+        self.mod2.write('import mod3\nprint(mod3)')
+        pymod = self.pycore.resource_to_pyobject(self.mod2)
+        self.assertEquals('import pkg2.mod3\nprint(pkg2.mod3)',
+                          self.import_tools.relatives_to_absolutes(pymod))
+
+    def test_transform_relatives_to_absolute_imports_for_aliases(self):
+        self.mod2.write('import mod3 as mod3\nprint(mod3)')
+        pymod = self.pycore.resource_to_pyobject(self.mod2)
+        self.assertEquals('import pkg2.mod3 as mod3\nprint(mod3)',
+                          self.import_tools.relatives_to_absolutes(pymod))
+
+    def test_organizing_imports(self):
+        self.mod1.write('import mod1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod1)
+        self.assertEquals('', self.import_tools.organize_imports(pymod))
+
+    def test_removing_self_imports(self):
+        self.mod.write('import mod\nmod.a_var = 1\nprint(mod.a_var)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
+                          self.import_tools.organize_imports(pymod))
+
+    def test_removing_self_imports2(self):
+        self.mod1.write('import pkg1.mod1\npkg1.mod1.a_var = 1\n'
+                        'print(pkg1.mod1.a_var)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod1)
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
+                          self.import_tools.organize_imports(pymod))
+
+    def test_removing_self_imports_with_as(self):
+        self.mod.write('import mod as mymod\n'
+                       'mymod.a_var = 1\nprint(mymod.a_var)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
+                          self.import_tools.organize_imports(pymod))
+
+    def test_removing_self_imports_for_froms(self):
+        self.mod1.write('from pkg1 import mod1\n'
+                        'mod1.a_var = 1\nprint(mod1.a_var)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod1)
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
+                          self.import_tools.organize_imports(pymod))
+
+    def test_removing_self_imports_for_froms_with_as(self):
+        self.mod1.write('from pkg1 import mod1 as mymod\n'
+                        'mymod.a_var = 1\nprint(mymod.a_var)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod1)
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
+                          self.import_tools.organize_imports(pymod))
+
+    def test_removing_self_imports_for_froms2(self):
+        self.mod.write('from mod import a_var\na_var = 1\nprint(a_var)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
+                          self.import_tools.organize_imports(pymod))
+
+    def test_removing_self_imports_for_froms3(self):
+        self.mod.write('from mod import a_var\na_var = 1\nprint(a_var)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
+                          self.import_tools.organize_imports(pymod))
+
+    def test_removing_self_imports_for_froms4(self):
+        self.mod.write('from mod import a_var as myvar\n'
+                       'a_var = 1\nprint(myvar)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('a_var = 1\nprint(a_var)\n',
+                          self.import_tools.organize_imports(pymod))
+
+    def test_removing_self_imports_with_no_dot_after_mod(self):
+        self.mod.write('import mod\nprint(mod)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('import mod\n\n\nprint(mod)\n',
+                          self.import_tools.organize_imports(pymod))
+
+    def test_removing_self_imports_with_no_dot_after_mod2(self):
+        self.mod.write('import mod\na_var = 1\n'
+                       'print(mod\\\n     \\\n     .var)\n\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('a_var = 1\nprint(var)\n\n',
+                          self.import_tools.organize_imports(pymod))
+
+    def test_removing_self_imports_for_from_import_star(self):
+        self.mod.write('from mod import *\na_var = 1\nprint(myvar)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('a_var = 1\nprint(myvar)\n',
+                          self.import_tools.organize_imports(pymod))
+
+    def test_not_removing_future_imports(self):
+        self.mod.write('from __future__ import division\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('from __future__ import division\n',
+                          self.import_tools.organize_imports(pymod))
+
+    def test_sorting_empty_imports(self):
+        self.mod.write('')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('', self.import_tools.sort_imports(pymod))
+
+    def test_sorting_one_import(self):
+        self.mod.write('import pkg1.mod1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('import pkg1.mod1\n',
+                          self.import_tools.sort_imports(pymod))
+
+    def test_sorting_imports_alphabetically(self):
+        self.mod.write('import pkg2.mod2\nimport pkg1.mod1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('import pkg1.mod1\nimport pkg2.mod2\n',
+                          self.import_tools.sort_imports(pymod))
+
+    def test_sorting_imports_and_froms(self):
+        self.mod.write('import pkg2.mod2\nfrom pkg1 import mod1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('import pkg2.mod2\nfrom pkg1 import mod1\n',
+                          self.import_tools.sort_imports(pymod))
+
+    def test_sorting_imports_and_standard_modules(self):
+        self.mod.write('import pkg1\nimport sys\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('import sys\n\nimport pkg1\n',
+                          self.import_tools.sort_imports(pymod))
+
+    def test_sorting_imports_and_standard_modules2(self):
+        self.mod.write('import sys\n\nimport time\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('import sys\nimport time\n',
+                          self.import_tools.sort_imports(pymod))
+
+    def test_sorting_only_standard_modules(self):
+        self.mod.write('import sys\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('import sys\n',
+                          self.import_tools.sort_imports(pymod))
+
+    def test_sorting_third_party(self):
+        self.mod.write('import pkg1\nimport a_third_party\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('import a_third_party\n\nimport pkg1\n',
+                          self.import_tools.sort_imports(pymod))
+
+    def test_sorting_only_third_parties(self):
+        self.mod.write('import a_third_party\na_var = 1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals('import a_third_party\n\n\na_var = 1\n',
+                          self.import_tools.sort_imports(pymod))
+
+    def test_simple_handling_long_imports(self):
+        self.mod.write('import pkg1.mod1\n\n\nm = pkg1.mod1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(
+            'import pkg1.mod1\n\n\nm = pkg1.mod1\n',
+            self.import_tools.handle_long_imports(pymod, maxdots=2))
+
+    def test_handling_long_imports_for_many_dots(self):
+        self.mod.write('import p1.p2.p3.m1\n\n\nm = p1.p2.p3.m1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(
+            'from p1.p2.p3 import m1\n\n\nm = m1\n',
+            self.import_tools.handle_long_imports(pymod, maxdots=2))
+
+    def test_handling_long_imports_for_their_length(self):
+        self.mod.write('import p1.p2.p3.m1\n\n\nm = p1.p2.p3.m1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(
+            'import p1.p2.p3.m1\n\n\nm = p1.p2.p3.m1\n',
+            self.import_tools.handle_long_imports(pymod, maxdots=3,
+                                                  maxlength=20))
+
+    def test_handling_long_imports_for_many_dots2(self):
+        self.mod.write('import p1.p2.p3.m1\n\n\nm = p1.p2.p3.m1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(
+            'from p1.p2.p3 import m1\n\n\nm = m1\n',
+            self.import_tools.handle_long_imports(pymod, maxdots=3,
+                                                  maxlength=10))
+
+    def test_handling_long_imports_with_one_letter_last(self):
+        self.mod.write('import p1.p2.p3.l\n\n\nm = p1.p2.p3.l\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(
+            'from p1.p2.p3 import l\n\n\nm = l\n',
+            self.import_tools.handle_long_imports(pymod, maxdots=2))
+
+    def test_empty_removing_unused_imports_and_eating_blank_lines(self):
+        self.mod.write('import pkg1\nimport pkg2\n\n\nprint(pkg1)\n')
+        pymod = self.pycore.get_module('mod')
+        module_with_imports = self.import_tools.module_imports(pymod)
+        module_with_imports.remove_unused_imports()
+        self.assertEquals('import pkg1\n\n\nprint(pkg1)\n',
+                          module_with_imports.get_changed_source())
+
+    def test_sorting_imports_moving_to_top(self):
+        self.mod.write('import mod\ndef f():\n    print(mod, pkg1, pkg2)\n'
+                       'import pkg1\nimport pkg2\n')
+        pymod = self.pycore.get_module('mod')
+        self.assertEquals('import mod\nimport pkg1\nimport pkg2\n\n\n'
+                          'def f():\n    print(mod, pkg1, pkg2)\n',
+                          self.import_tools.sort_imports(pymod))
+
+    def test_sorting_imports_moving_to_top2(self):
+        self.mod.write('def f():\n    print(mod)\nimport mod\n')
+        pymod = self.pycore.get_module('mod')
+        self.assertEquals('import mod\n\n\ndef f():\n    print(mod)\n',
+                          self.import_tools.sort_imports(pymod))
+
+    def test_sorting_imports_moving_to_top_and_module_docs(self):
+        self.mod.write('"""\ndocs\n"""\ndef f():\n    print(mod)\nimport mod\n')
+        pymod = self.pycore.get_module('mod')
+        self.assertEquals(
+            '"""\ndocs\n"""\nimport mod\n\n\ndef f():\n    print(mod)\n',
+            self.import_tools.sort_imports(pymod))
+
+    def test_sorting_future_imports(self):
+        self.mod.write('import os\nfrom __future__ import devision\n')
+        pymod = self.pycore.get_module('mod')
+        self.assertEquals(
+            'from __future__ import devision\n\nimport os\n',
+            self.import_tools.sort_imports(pymod))
+
+    def test_customized_import_organization(self):
+        self.mod.write('import sys\nimport sys\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(
+            'import sys\n',
+            self.import_tools.organize_imports(pymod, unused=False))
+
+    def test_customized_import_organization2(self):
+        self.mod.write('import sys\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(
+            'import sys\n',
+            self.import_tools.organize_imports(pymod, unused=False))
+
+    def test_customized_import_organization3(self):
+        self.mod.write('import sys\nimport mod\n\n\nvar = 1\nprint(mod.var)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(
+            'import sys\n\n\nvar = 1\nprint(var)\n',
+            self.import_tools.organize_imports(pymod, unused=False))
+
+    def test_trivial_filtered_expand_stars(self):
+        self.pkg1.get_child('__init__.py').write('var1 = 1\n')
+        self.pkg2.get_child('__init__.py').write('var2 = 1\n')
+        self.mod.write('from pkg1 import *\nfrom pkg2 import *\n\n'
+                       'print(var1, var2)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(
+            'from pkg1 import *\nfrom pkg2 import *\n\nprint(var1, var2)\n',
+             self.import_tools.expand_stars(pymod, lambda stmt: False))
+
+    def _line_filter(self, lineno):
+        def import_filter(import_stmt):
+            return import_stmt.start_line <= lineno < import_stmt.end_line
+        return import_filter
+
+    def test_filtered_expand_stars(self):
+        self.pkg1.get_child('__init__.py').write('var1 = 1\n')
+        self.pkg2.get_child('__init__.py').write('var2 = 1\n')
+        self.mod.write('from pkg1 import *\nfrom pkg2 import *\n\n'
+                       'print(var1, var2)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(
+            'from pkg1 import *\nfrom pkg2 import var2\n\nprint(var1, var2)\n',
+             self.import_tools.expand_stars(pymod, self._line_filter(2)))
+
+    def test_filtered_relative_to_absolute(self):
+        self.mod3.write('var = 1')
+        self.mod2.write('import mod3\n\nprint(mod3.var)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod2)
+        self.assertEquals(
+            'import mod3\n\nprint(mod3.var)\n',
+             self.import_tools.relatives_to_absolutes(
+                          pymod, lambda stmt: False))
+        self.assertEquals(
+            'import pkg2.mod3\n\nprint(pkg2.mod3.var)\n',
+             self.import_tools.relatives_to_absolutes(
+                          pymod, self._line_filter(1)))
+
+    def test_filtered_froms_to_normals(self):
+        self.pkg1.get_child('__init__.py').write('var1 = 1\n')
+        self.pkg2.get_child('__init__.py').write('var2 = 1\n')
+        self.mod.write('from pkg1 import var1\nfrom pkg2 import var2\n\n'
+                       'print(var1, var2)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(
+            'from pkg1 import var1\nfrom pkg2 import var2\n\nprint(var1, var2)\n',
+             self.import_tools.expand_stars(pymod, lambda stmt: False))
+        self.assertEquals(
+            'from pkg1 import var1\nimport pkg2\n\nprint(var1, pkg2.var2)\n',
+             self.import_tools.froms_to_imports(pymod, self._line_filter(2)))
+
+    def test_filtered_froms_to_normals2(self):
+        self.pkg1.get_child('__init__.py').write('var1 = 1\n')
+        self.pkg2.get_child('__init__.py').write('var2 = 1\n')
+        self.mod.write('from pkg1 import *\nfrom pkg2 import *\n\n'
+                       'print(var1, var2)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(
+            'from pkg1 import *\nimport pkg2\n\nprint(var1, pkg2.var2)\n',
+             self.import_tools.froms_to_imports(pymod, self._line_filter(2)))
+
+    def test_filtered_handle_long_imports(self):
+        self.mod.write('import p1.p2.p3.m1\nimport pkg1.mod1\n\n\n'
+                       'm = p1.p2.p3.m1, pkg1.mod1\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(
+            'import p1.p2.p3.m1\nfrom pkg1 import mod1\n\n\n'
+            'm = p1.p2.p3.m1, mod1\n',
+            self.import_tools.handle_long_imports(
+                          pymod, maxlength=5,
+                          import_filter=self._line_filter(2)))
+
+    def test_filtering_and_import_actions_with_more_than_one_phase(self):
+        self.pkg1.get_child('__init__.py').write('var1 = 1\n')
+        self.pkg2.get_child('__init__.py').write('var2 = 1\n')
+        self.mod.write('from pkg1 import *\nfrom pkg2 import *\n\n'
+                       'print(var2)\n')
+        pymod = self.pycore.resource_to_pyobject(self.mod)
+        self.assertEquals(
+            'from pkg2 import *\n\nprint(var2)\n',
+             self.import_tools.expand_stars(pymod, self._line_filter(1)))
+
+    def test_non_existent_module_and_used_imports(self):
+        self.mod.write(
+            'from does_not_exist import func\n\nfunc()\n')
+        pymod = self.pycore.get_module('mod')
+
+        module_with_imports = self.import_tools.module_imports(pymod)
+        imports = module_with_imports.get_used_imports(pymod)
+        self.assertEquals(1, len(imports))
+
+
+class AddImportTest(unittest.TestCase):
+
+    def setUp(self):
+        super(AddImportTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+
+        self.mod1 = testutils.create_module(self.project, 'mod1')
+        self.mod2 = testutils.create_module(self.project, 'mod2')
+        self.pkg = testutils.create_package(self.project, 'pkg')
+        self.mod3 = testutils.create_module(self.project, 'mod3', self.pkg)
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(AddImportTest, self).tearDown()
+
+    def test_normal_imports(self):
+        self.mod2.write('myvar = None\n')
+        self.mod1.write('\n')
+        pymod = self.pycore.get_module('mod1')
+        result, name = add_import(self.pycore, pymod, 'mod2', 'myvar')
+        self.assertEquals('import mod2\n', result)
+        self.assertEquals('mod2.myvar', name)
+
+    def test_not_reimporting_a_name(self):
+        self.mod2.write('myvar = None\n')
+        self.mod1.write('from mod2 import myvar\n')
+        pymod = self.pycore.get_module('mod1')
+        result, name = add_import(self.pycore, pymod, 'mod2', 'myvar')
+        self.assertEquals('from mod2 import myvar\n', result)
+        self.assertEquals('myvar', name)
+
+    def test_adding_import_when_siblings_are_imported(self):
+        self.mod2.write('var1 = None\nvar2 = None\n')
+        self.mod1.write('from mod2 import var1\n')
+        pymod = self.pycore.get_module('mod1')
+        result, name = add_import(self.pycore, pymod, 'mod2', 'var2')
+        self.assertEquals('from mod2 import var1, var2\n', result)
+        self.assertEquals('var2', name)
+
+    def test_adding_import_when_the_package_is_imported(self):
+        self.pkg.get_child('__init__.py').write('var1 = None\n')
+        self.mod3.write('var2 = None\n')
+        self.mod1.write('from pkg import var1\n')
+        pymod = self.pycore.get_module('mod1')
+        result, name = add_import(self.pycore, pymod, 'pkg.mod3', 'var2')
+        self.assertEquals('from pkg import var1, mod3\n', result)
+        self.assertEquals('mod3.var2', name)
+
+    def test_adding_import_for_modules_instead_of_names(self):
+        self.pkg.get_child('__init__.py').write('var1 = None\n')
+        self.mod3.write('\n')
+        self.mod1.write('from pkg import var1\n')
+        pymod = self.pycore.get_module('mod1')
+        result, name = add_import(self.pycore, pymod, 'pkg.mod3', None)
+        self.assertEquals('from pkg import var1, mod3\n', result)
+        self.assertEquals('mod3', name)
+
+    def test_adding_import_for_modules_with_normal_duplicate_imports(self):
+        self.pkg.get_child('__init__.py').write('var1 = None\n')
+        self.mod3.write('\n')
+        self.mod1.write('import pkg.mod3\n')
+        pymod = self.pycore.get_module('mod1')
+        result, name = add_import(self.pycore, pymod, 'pkg.mod3', None)
+        self.assertEquals('import pkg.mod3\n', result)
+        self.assertEquals('pkg.mod3', name)
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(ImportUtilsTest))
+    result.addTests(unittest.makeSuite(AddImportTest))
+    return result
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/refactor/inlinetest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,616 @@
+from ropetest.testutils import only_for
+import unittest
+
+import rope.base.exceptions
+from rope.refactor import inline
+from ropetest import testutils
+
+
+class InlineTest(unittest.TestCase):
+
+    def setUp(self):
+        super(InlineTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+        self.mod = testutils.create_module(self.project, 'mod')
+        self.mod2 = testutils.create_module(self.project, 'mod2')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(InlineTest, self).tearDown()
+
+    def _inline(self, code, offset, **kwds):
+        self.mod.write(code)
+        self._inline2(self.mod, offset, **kwds)
+        return self.mod.read()
+
+    def _inline2(self, resource, offset, **kwds):
+        inliner = inline.create_inline(self.project, resource, offset)
+        changes = inliner.get_changes(**kwds)
+        self.project.do(changes)
+        return self.mod.read()
+
+    def test_simple_case(self):
+        code = 'a_var = 10\nanother_var = a_var\n'
+        refactored = self._inline(code, code.index('a_var') + 1)
+        self.assertEquals('another_var = 10\n', refactored)
+
+    def test_empty_case(self):
+        code = 'a_var = 10\n'
+        refactored = self._inline(code, code.index('a_var') + 1)
+        self.assertEquals('', refactored)
+
+    def test_long_definition(self):
+        code = 'a_var = 10 + (10 + 10)\nanother_var = a_var\n'
+        refactored = self._inline(code, code.index('a_var') + 1)
+        self.assertEquals('another_var = 10 + (10 + 10)\n', refactored)
+
+    def test_explicit_continuation(self):
+        code = 'a_var = (10 +\n 10)\nanother_var = a_var\n'
+        refactored = self._inline(code, code.index('a_var') + 1)
+        self.assertEquals('another_var = (10 + 10)\n', refactored)
+
+    def test_implicit_continuation(self):
+        code = 'a_var = 10 +\\\n       10\nanother_var = a_var\n'
+        refactored = self._inline(code, code.index('a_var') + 1)
+        self.assertEquals('another_var = 10 + 10\n', refactored)
+
+    def test_inlining_at_the_end_of_input(self):
+        code = 'a = 1\nb = a'
+        refactored = self._inline(code, code.index('a') + 1)
+        self.assertEquals('b = 1', refactored)
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_on_classes(self):
+        code = 'class AClass(object):\n    pass\n'
+        refactored = self._inline(code, code.index('AClass') + 1)
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_multiple_assignments(self):
+        code = 'a_var = 10\na_var = 20\n'
+        refactored = self._inline(code, code.index('a_var') + 1)
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_tuple_assignments(self):
+        code = 'a_var, another_var = (20, 30)\n'
+        refactored = self._inline(code, code.index('a_var') + 1)
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_on_unknown_vars(self):
+        code = 'a_var = another_var\n'
+        refactored = self._inline(code, code.index('another_var') + 1)
+
+    def test_attribute_inlining(self):
+        code = 'class A(object):\n    def __init__(self):\n' \
+               '        self.an_attr = 3\n        range(self.an_attr)\n'
+        refactored = self._inline(code, code.index('an_attr') + 1)
+        expected = 'class A(object):\n    def __init__(self):\n' \
+                   '        range(3)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_attribute_inlining2(self):
+        code = 'class A(object):\n    def __init__(self):\n' \
+               '        self.an_attr = 3\n        range(self.an_attr)\n' \
+               'a = A()\nrange(a.an_attr)'
+        refactored = self._inline(code, code.index('an_attr') + 1)
+        expected = 'class A(object):\n    def __init__(self):\n' \
+                   '        range(3)\n' \
+                   'a = A()\nrange(3)'
+        self.assertEquals(expected, refactored)
+
+
+    def test_a_function_with_no_occurance(self):
+        self.mod.write('def a_func():\n    pass\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('', self.mod.read())
+
+    def test_a_function_with_no_occurance2(self):
+        self.mod.write('a_var = 10\ndef a_func():\n    pass\nprint(a_var)\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('a_var = 10\nprint(a_var)\n', self.mod.read())
+
+    def test_replacing_calls_with_function_definition_in_other_modules(self):
+        self.mod.write('def a_func():\n    print(1)\n')
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('import mod\nmod.a_func()\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('import mod\nprint(1)\n', mod1.read())
+
+    def test_replacing_calls_with_function_definition_in_other_modules2(self):
+        self.mod.write('def a_func():\n    print(1)\n')
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('import mod\nif True:\n    mod.a_func()\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('import mod\nif True:\n    print(1)\n', mod1.read())
+
+    def test_replacing_calls_with_method_definition_in_other_modules(self):
+        self.mod.write('class A(object):\n    var = 10\n'
+                       '    def a_func(self):\n        print(1)\n')
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('import mod\nmod.A().a_func()\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('import mod\nprint(1)\n', mod1.read())
+        self.assertEquals('class A(object):\n    var = 10\n', self.mod.read())
+
+    def test_replacing_calls_with_function_definition_in_defining_module(self):
+        self.mod.write('def a_func():\n    print(1)\na_func()\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('print(1)\n', self.mod.read())
+
+    def test_replacing_calls_with_function_definition_in_defining_module2(self):
+        self.mod.write('def a_func():\n    for i in range(10):\n        print(1)\na_func()\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('for i in range(10):\n    print(1)\n', self.mod.read())
+
+    def test_replacing_calls_with_method_definition_in_defining_modules(self):
+        self.mod.write('class A(object):\n    var = 10\n'
+                       '    def a_func(self):\n        print(1)\nA().a_func()')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('class A(object):\n    var = 10\nprint(1)\n', self.mod.read())
+
+    def test_parameters_with_the_same_name_as_passed(self):
+        self.mod.write('def a_func(var):\n    print(var)\nvar = 1\na_func(var)\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('var = 1\nprint(var)\n', self.mod.read())
+
+    def test_parameters_with_the_same_name_as_passed2(self):
+        self.mod.write('def a_func(var):\n    print(var)\nvar = 1\na_func(var=var)\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('var = 1\nprint(var)\n', self.mod.read())
+
+    def test_simple_parameters_renaming(self):
+        self.mod.write('def a_func(param):\n    print(param)\nvar = 1\na_func(var)\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('var = 1\nprint(var)\n', self.mod.read())
+
+    def test_simple_parameters_renaming_for_multiple_params(self):
+        self.mod.write('def a_func(param1, param2):\n    p = param1 + param2\n'
+                       'var1 = 1\nvar2 = 1\na_func(var1, var2)\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('var1 = 1\nvar2 = 1\np = var1 + var2\n', self.mod.read())
+
+    def test_parameters_renaming_for_passed_constants(self):
+        self.mod.write('def a_func(param):\n    print(param)\na_func(1)\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('print(1)\n', self.mod.read())
+
+    def test_parameters_renaming_for_passed_statements(self):
+        self.mod.write('def a_func(param):\n    print(param)\na_func((1 + 2) / 3)\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('print((1 + 2) / 3)\n', self.mod.read())
+
+    def test_simple_parameters_renaming_for_multiple_params_using_keywords(self):
+        self.mod.write('def a_func(param1, param2):\n    p = param1 + param2\n'
+                       'var1 = 1\nvar2 = 1\na_func(param2=var1, param1=var2)\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('var1 = 1\nvar2 = 1\np = var2 + var1\n', self.mod.read())
+
+    def test_simple_parameters_renaming_for_multiple_params_using_mixed_keywords(self):
+        self.mod.write('def a_func(param1, param2):\n    p = param1 + param2\n'
+                       'var1 = 1\nvar2 = 1\na_func(var2, param2=var1)\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('var1 = 1\nvar2 = 1\np = var2 + var1\n', self.mod.read())
+
+    def test_simple_putting_in_default_arguments(self):
+        self.mod.write('def a_func(param=None):\n    print(param)\n'
+                       'a_func()\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('print(None)\n', self.mod.read())
+
+    def test_overriding_default_arguments(self):
+        self.mod.write('def a_func(param1=1, param2=2):\n    print(param1, param2)\n'
+                       'a_func(param2=3)\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('print(1, 3)\n', self.mod.read())
+
+    def test_badly_formatted_text(self):
+        self.mod.write('def a_func  (  param1 =  1 ,param2 = 2 )  :\n    print(param1, param2)\n'
+                       'a_func  ( param2 \n  = 3 )  \n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('print(1, 3)\n', self.mod.read())
+
+    def test_passing_first_arguments_for_methods(self):
+        a_class = 'class A(object):\n' \
+                  '    def __init__(self):\n' \
+                  '        self.var = 1\n' \
+                  '        self.a_func(self.var)\n' \
+                  '    def a_func(self, param):\n' \
+                  '        print(param)\n'
+        self.mod.write(a_class)
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        expected = 'class A(object):\n' \
+                   '    def __init__(self):\n' \
+                   '        self.var = 1\n' \
+                   '        print(self.var)\n'
+        self.assertEquals(expected, self.mod.read())
+
+    def test_passing_first_arguments_for_methods2(self):
+        a_class = 'class A(object):\n' \
+                  '    def __init__(self):\n' \
+                  '        self.var = 1\n' \
+                  '    def a_func(self, param):\n' \
+                  '        print(param, self.var)\n' \
+                  'an_a = A()\n' \
+                  'an_a.a_func(1)\n'
+        self.mod.write(a_class)
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        expected = 'class A(object):\n' \
+                   '    def __init__(self):\n' \
+                   '        self.var = 1\n' \
+                   'an_a = A()\n' \
+                   'print(1, an_a.var)\n'
+        self.assertEquals(expected, self.mod.read())
+
+    def test_passing_first_arguments_for_methods3(self):
+        a_class = 'class A(object):\n' \
+                  '    def __init__(self):\n' \
+                  '        self.var = 1\n' \
+                  '    def a_func(self, param):\n' \
+                  '        print(param, self.var)\n' \
+                  'an_a = A()\n' \
+                  'A.a_func(an_a, 1)\n'
+        self.mod.write(a_class)
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        expected = 'class A(object):\n' \
+                   '    def __init__(self):\n' \
+                   '        self.var = 1\n' \
+                   'an_a = A()\n' \
+                   'print(1, an_a.var)\n'
+        self.assertEquals(expected, self.mod.read())
+
+    def test_inlining_staticmethods(self):
+        a_class = 'class A(object):\n' \
+                  '    @staticmethod\n' \
+                  '    def a_func(param):\n' \
+                  '        print(param)\n' \
+                  'A.a_func(1)\n'
+        self.mod.write(a_class)
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        expected = 'class A(object):\n' \
+                   '    pass\n' \
+                  'print(1)\n'
+        self.assertEquals(expected, self.mod.read())
+
+    def test_static_methods2(self):
+        a_class = 'class A(object):\n' \
+                  '    var = 10\n' \
+                  '    @staticmethod\n' \
+                  '    def a_func(param):\n' \
+                  '        print(param)\n' \
+                  'an_a = A()\n' \
+                  'an_a.a_func(1)\n' \
+                  'A.a_func(2)\n'
+        self.mod.write(a_class)
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        expected = 'class A(object):\n' \
+                  '    var = 10\n' \
+                  'an_a = A()\n' \
+                  'print(1)\n' \
+                  'print(2)\n'
+        self.assertEquals(expected, self.mod.read())
+
+    def test_inlining_classmethods(self):
+        a_class = 'class A(object):\n' \
+                  '    @classmethod\n' \
+                  '    def a_func(cls, param):\n' \
+                  '        print(param)\n' \
+                  'A.a_func(1)\n'
+        self.mod.write(a_class)
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        expected = 'class A(object):\n' \
+                   '    pass\n' \
+                   'print(1)\n'
+        self.assertEquals(expected, self.mod.read())
+
+    def test_inlining_classmethods2(self):
+        a_class = 'class A(object):\n' \
+                  '    @classmethod\n' \
+                  '    def a_func(cls, param):\n' \
+                  '        return cls\n' \
+                  'print(A.a_func(1))\n'
+        self.mod.write(a_class)
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        expected = 'class A(object):\n' \
+                   '    pass\n' \
+                   'print(A)\n'
+        self.assertEquals(expected, self.mod.read())
+
+    def test_simple_return_values_and_inlining_functions(self):
+        self.mod.write('def a_func():\n    return 1\na = a_func()\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('a = 1\n',
+                          self.mod.read())
+
+    def test_simple_return_values_and_inlining_lonely_functions(self):
+        self.mod.write('def a_func():\n    return 1\na_func()\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('1\n', self.mod.read())
+
+    def test_empty_returns_and_inlining_lonely_functions(self):
+        self.mod.write('def a_func():\n    if True:\n        return\na_func()\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('if True:\n    pass\n', self.mod.read())
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_multiple_returns(self):
+        self.mod.write('def less_than_five(var):\n    if var < 5:\n'
+                       '        return True\n    return False\n'
+                       'a = less_than_five(2)\n')
+        self._inline2(self.mod, self.mod.read().index('less') + 1)
+
+    def test_multiple_returns_and_not_using_the_value(self):
+        self.mod.write('def less_than_five(var):\n    if var < 5:\n'
+                       '        return True\n    return False\nless_than_five(2)\n')
+        self._inline2(self.mod, self.mod.read().index('less') + 1)
+        self.assertEquals('if 2 < 5:\n    True\nFalse\n', self.mod.read())
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_raising_exception_for_list_arguments(self):
+        self.mod.write('def a_func(*args):\n    print(args)\na_func(1)\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_raising_exception_for_list_keywods(self):
+        self.mod.write('def a_func(**kwds):\n    print(kwds)\na_func(n=1)\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+
+    def test_function_parameters_and_returns_in_other_functions(self):
+        code = 'def a_func(param1, param2):\n' \
+               '    return param1 + param2\n' \
+               'range(a_func(20, param2=abs(10)))\n'
+        self.mod.write(code)
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('range(20 + abs(10))\n', self.mod.read())
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_function_references_other_than_call(self):
+        self.mod.write('def a_func(param):\n    print(param)\nf = a_func\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_function_referencing_itself(self):
+        self.mod.write('def a_func(var):\n    func = a_func\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+
+    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
+    def test_recursive_functions(self):
+        self.mod.write('def a_func(var):\n    a_func(var)\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+
+    # TODO: inlining on function parameters
+    def xxx_test_inlining_function_default_parameters(self):
+        self.mod.write('def a_func(p1=1):\n    pass\na_func()\n')
+        self._inline2(self.mod, self.mod.read().index('p1') + 1)
+        self.assertEquals('def a_func(p1=1):\n    pass\na_func()\n', self.mod.read())
+
+    def test_simple_inlining_after_extra_indented_lines(self):
+        self.mod.write('def a_func():\n    for i in range(10):\n        pass\n'
+                       'if True:\n    pass\na_func()\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('if True:\n    pass\nfor i in range(10):\n    pass\n',
+                          self.mod.read())
+
+    def test_inlining_a_function_with_pydoc(self):
+        self.mod.write('def a_func():\n    """docs"""\n    a = 1\na_func()')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('a = 1\n', self.mod.read())
+
+    def test_inlining_methods(self):
+        self.mod.write("class A(object):\n    name = 'hey'\n"
+                       "    def get_name(self):\n        return self.name\n"
+                       "a = A()\nname = a.get_name()\n")
+        self._inline2(self.mod, self.mod.read().rindex('get_name') + 1)
+        self.assertEquals("class A(object):\n    name = 'hey'\n"
+                          "a = A()\nname = a.name\n", self.mod.read())
+
+    def test_simple_returns_with_backslashes(self):
+        self.mod.write('def a_func():\n    return 1\\\n        + 2\na = a_func()\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('a = 1 + 2\n', self.mod.read())
+
+    def test_a_function_with_pass_body(self):
+        self.mod.write('def a_func():\n    print(1)\na = a_func()\n')
+        self._inline2(self.mod, self.mod.read().index('a_func') + 1)
+        self.assertEquals('print(1)\na = None\n', self.mod.read())
+
+    def test_inlining_the_last_method_of_a_class(self):
+        self.mod.write('class A(object):\n'
+                       '    def a_func(self):\n        pass\n')
+        self._inline2(self.mod, self.mod.read().rindex('a_func') + 1)
+        self.assertEquals('class A(object):\n    pass\n',
+                          self.mod.read())
+
+    def test_adding_needed_imports_in_the_dest_module(self):
+        self.mod.write('import sys\n\ndef ver():\n    print(sys.version)\n')
+        self.mod2.write('import mod\n\nmod.ver()')
+        self._inline2(self.mod, self.mod.read().index('ver') + 1)
+        self.assertEquals('import mod\nimport sys\n\nprint(sys.version)\n',
+                          self.mod2.read())
+
+    def test_adding_needed_imports_in_the_dest_module_removing_selfs(self):
+        self.mod.write('import mod2\n\ndef f():\n    print(mod2.var)\n')
+        self.mod2.write('import mod\n\nvar = 1\nmod.f()\n')
+        self._inline2(self.mod, self.mod.read().index('f(') + 1)
+        self.assertEquals('import mod\n\nvar = 1\nprint(var)\n',
+                          self.mod2.read())
+
+    def test_handling_relative_imports_when_inlining(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod3 = testutils.create_module(self.project, 'mod3', pkg)
+        mod4 = testutils.create_module(self.project, 'mod4', pkg)
+        mod4.write('var = 1\n')
+        mod3.write('from . import mod4\n\ndef f():\n    print(mod4.var)\n')
+        self.mod.write('import pkg.mod3\n\npkg.mod3.f()\n')
+        self._inline2(self.mod, self.mod.read().index('f(') + 1)
+        # Cannot determine the exact import
+        self.assertTrue('\n\nprint(mod4.var)\n' in self.mod.read())
+
+    def test_adding_needed_imports_for_elements_in_source(self):
+        self.mod.write('def f1():\n    return f2()\ndef f2():\n    return 1\n')
+        self.mod2.write('import mod\n\nprint(mod.f1())\n')
+        self._inline2(self.mod, self.mod.read().index('f1') + 1)
+        self.assertEquals('import mod\nfrom mod import f2\n\nprint(f2())\n',
+                          self.mod2.read())
+
+    def test_relative_imports_and_changing_inlining_body(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod3 = testutils.create_module(self.project, 'mod3', pkg)
+        mod4 = testutils.create_module(self.project, 'mod4', pkg)
+        mod4.write('var = 1\n')
+        mod3.write('import mod4\n\ndef f():\n    print(mod4.var)\n')
+        self.mod.write('import pkg.mod3\n\npkg.mod3.f()\n')
+        self._inline2(self.mod, self.mod.read().index('f(') + 1)
+        self.assertEquals(
+            'import pkg.mod3\nimport pkg.mod4\n\nprint(pkg.mod4.var)\n',
+            self.mod.read())
+
+    def test_inlining_with_different_returns(self):
+        self.mod.write('def f(p):\n    return p\n'
+                       'print(f(1))\nprint(f(2))\nprint(f(1))\n')
+        self._inline2(self.mod, self.mod.read().index('f(') + 1)
+        self.assertEquals('print(1)\nprint(2)\nprint(1)\n',
+                          self.mod.read())
+
+    def test_not_removing_definition_for_variables(self):
+        code = 'a_var = 10\nanother_var = a_var\n'
+        refactored = self._inline(code, code.index('a_var') + 1,
+                                  remove=False)
+        self.assertEquals('a_var = 10\nanother_var = 10\n', refactored)
+
+    def test_not_removing_definition_for_methods(self):
+        code = 'def func():\n    print(1)\n\nfunc()\n'
+        refactored = self._inline(code, code.index('func') + 1,
+                                  remove=False)
+        self.assertEquals('def func():\n    print(1)\n\nprint(1)\n',
+                          refactored)
+
+    def test_only_current_for_methods(self):
+        code = 'def func():\n    print(1)\n\nfunc()\nfunc()\n'
+        refactored = self._inline(code, code.rindex('func') + 1,
+                                  remove=False, only_current=True)
+        self.assertEquals('def func():\n    print(1)\n\nfunc()\nprint(1)\n',
+                          refactored)
+
+    def test_only_current_for_variables(self):
+        code = 'one = 1\n\na = one\nb = one\n'
+        refactored = self._inline(code, code.rindex('one') + 1,
+                                  remove=False, only_current=True)
+        self.assertEquals('one = 1\n\na = one\nb = 1\n', refactored)
+
+    def test_inlining_one_line_functions(self):
+        code = 'def f(): return 1\nvar = f()\n'
+        refactored = self._inline(code, code.rindex('f'))
+        self.assertEquals('var = 1\n', refactored)
+
+    def test_inlining_one_line_functions_with_breaks(self):
+        code = 'def f(\np): return p\nvar = f(1)\n'
+        refactored = self._inline(code, code.rindex('f'))
+        self.assertEquals('var = 1\n', refactored)
+
+    def test_inlining_one_line_functions_with_breaks2(self):
+        code = 'def f(\n): return 1\nvar = f()\n'
+        refactored = self._inline(code, code.rindex('f'))
+        self.assertEquals('var = 1\n', refactored)
+
+    def test_resources_parameter(self):
+        self.mod.write('def a_func():\n    print(1)\n')
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('import mod\nmod.a_func()\n')
+        self._inline2(self.mod, self.mod.read().index('a_func'),
+                      resources=[self.mod])
+        self.assertEquals('', self.mod.read())
+        self.assertEquals('import mod\nmod.a_func()\n', mod1.read())
+
+    def test_inlining_parameters(self):
+        code = 'def f(p=1):\n    pass\nf()\n'
+        result = self._inline(code, code.index('p'))
+        self.assertEquals('def f(p=1):\n    pass\nf(1)\n', result)
+
+    def test_inlining_function_with_line_breaks_in_args(self):
+        code = 'def f(p): return p\nvar = f(1 +\n1)\n'
+        refactored = self._inline(code, code.rindex('f'))
+        self.assertEquals('var = 1 + 1\n', refactored)
+
+    def test_inlining_variables_before_comparison(self):
+        code = 'start = 1\nprint(start <= 2)\n'
+        refactored = self._inline(code, code.index('start'))
+        self.assertEquals('print(1 <= 2)\n', refactored)
+
+    def test_inlining_variables_in_other_modules(self):
+        self.mod.write('myvar = 1\n')
+        self.mod2.write('import mod\nprint(mod.myvar)\n')
+        self._inline2(self.mod, 2)
+        self.assertEquals('import mod\nprint(1)\n', self.mod2.read())
+
+    def test_inlining_variables_and_back_importing(self):
+        self.mod.write('mainvar = 1\nmyvar = mainvar\n')
+        self.mod2.write('import mod\nprint(mod.myvar)\n')
+        self._inline2(self.mod, self.mod.read().index('myvar'))
+        expected = 'import mod\n' \
+                   'from mod import mainvar\n' \
+                   'print(mainvar)\n'
+        self.assertEquals(expected, self.mod2.read())
+
+    def test_inlining_variables_and_importing_used_imports(self):
+        self.mod.write('import sys\nmyvar = sys.argv\n')
+        self.mod2.write('import mod\nprint(mod.myvar)\n')
+        self._inline2(self.mod, self.mod.read().index('myvar'))
+        expected = 'import mod\n' \
+                   'import sys\n' \
+                   'print(sys.argv)\n'
+        self.assertEquals(expected, self.mod2.read())
+
+    def test_inlining_variables_and_removing_old_froms(self):
+        self.mod.write('var = 1\n')
+        self.mod2.write('from mod import var\nprint(var)\n')
+        self._inline2(self.mod2, self.mod2.read().rindex('var'))
+        self.assertEquals('print(1)\n', self.mod2.read())
+
+    def test_inlining_method_and_removing_old_froms(self):
+        self.mod.write('def f():    return 1\n')
+        self.mod2.write('from mod import f\nprint(f())\n')
+        self._inline2(self.mod2, self.mod2.read().rindex('f'))
+        self.assertEquals('print(1)\n', self.mod2.read())
+
+    def test_inlining_functions_in_other_modules_and_only_current(self):
+        code1 = 'def f():\n' \
+                '    return 1\n' \
+                'print(f())\n'
+        code2 = 'import mod\n' \
+                'print(mod.f())\n' \
+                'print(mod.f())\n'
+        self.mod.write(code1)
+        self.mod2.write(code2)
+        self._inline2(self.mod2, self.mod2.read().rindex('f'),
+                      remove=False, only_current=True)
+        expected2 = 'import mod\n' \
+                    'print(mod.f())\n' \
+                    'print(1)\n'
+        self.assertEquals(code1, self.mod.read())
+        self.assertEquals(expected2, self.mod2.read())
+
+    def test_inlining_variables_in_other_modules_and_only_current(self):
+        code1 = 'var = 1\n' \
+                'print(var)\n'
+        code2 = 'import mod\n' \
+                'print(mod.var)\n' \
+                'print(mod.var)\n'
+        self.mod.write(code1)
+        self.mod2.write(code2)
+        self._inline2(self.mod2, self.mod2.read().rindex('var'),
+                      remove=False, only_current=True)
+        expected2 = 'import mod\n' \
+                    'print(mod.var)\n' \
+                    'print(1)\n'
+        self.assertEquals(code1, self.mod.read())
+        self.assertEquals(expected2, self.mod2.read())
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(InlineTest))
+    return result
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/refactor/movetest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,507 @@
+import unittest
+
+from rope.base import exceptions
+from rope.refactor import move
+from ropetest import testutils
+
+
+class MoveRefactoringTest(unittest.TestCase):
+
+    def setUp(self):
+        super(MoveRefactoringTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+        self.mod1 = testutils.create_module(self.project, 'mod1')
+        self.mod2 = testutils.create_module(self.project, 'mod2')
+        self.mod3 = testutils.create_module(self.project, 'mod3')
+        self.pkg = testutils.create_package(self.project, 'pkg')
+        self.mod4 = testutils.create_module(self.project, 'mod4', self.pkg)
+        self.mod5 = testutils.create_module(self.project, 'mod5', self.pkg)
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(MoveRefactoringTest, self).tearDown()
+
+    def _move(self, resource, offset, dest_resource):
+        changes = move.create_move(self.project, resource, offset).\
+                  get_changes(dest_resource)
+        self.project.do(changes)
+
+    def test_simple_moving(self):
+        self.mod1.write('class AClass(object):\n    pass\n')
+        self._move(self.mod1, self.mod1.read().index('AClass') + 1,
+                              self.mod2)
+        self.assertEquals('', self.mod1.read())
+        self.assertEquals('class AClass(object):\n    pass\n',
+                          self.mod2.read())
+
+    def test_changing_other_modules_adding_normal_imports(self):
+        self.mod1.write('class AClass(object):\n    pass\n')
+        self.mod3.write('import mod1\na_var = mod1.AClass()\n')
+        self._move(self.mod1, self.mod1.read().index('AClass') + 1,
+                   self.mod2)
+        self.assertEquals('import mod1\nimport mod2\na_var = mod2.AClass()\n',
+                          self.mod3.read())
+
+    def test_changing_other_modules_removing_from_imports(self):
+        self.mod1.write('class AClass(object):\n    pass\n')
+        self.mod3.write('from mod1 import AClass\na_var = AClass()\n')
+        self._move(self.mod1, self.mod1.read().index('AClass') + 1,
+                   self.mod2)
+        self.assertEquals('import mod2\na_var = mod2.AClass()\n',
+                          self.mod3.read())
+
+    def test_changing_source_module(self):
+        self.mod1.write('class AClass(object):\n    pass\na_var = AClass()\n')
+        self._move(self.mod1, self.mod1.read().index('AClass') + 1,
+                   self.mod2)
+        self.assertEquals('import mod2\na_var = mod2.AClass()\n',
+                          self.mod1.read())
+
+    def test_changing_destination_module(self):
+        self.mod1.write('class AClass(object):\n    pass\n')
+        self.mod2.write('from mod1 import AClass\na_var = AClass()\n')
+        self._move(self.mod1, self.mod1.read().index('AClass') + 1,
+                   self.mod2)
+        self.assertEquals('class AClass(object):\n    pass\na_var = AClass()\n',
+                          self.mod2.read())
+
+    @testutils.assert_raises(exceptions.RefactoringError)
+    def test_folder_destination(self):
+        folder = self.project.root.create_folder('folder')
+        self.mod1.write('class AClass(object):\n    pass\n')
+        self._move(self.mod1, self.mod1.read().index('AClass') + 1, folder)
+
+    @testutils.assert_raises(exceptions.RefactoringError)
+    def test_raising_exception_for_moving_non_global_elements(self):
+        self.mod1.write('def a_func():\n    class AClass(object):\n        pass\n')
+        self._move(self.mod1, self.mod1.read().index('AClass') + 1,
+                   self.mod2)
+
+    @testutils.assert_raises(exceptions.RefactoringError)
+    def test_raising_exception_for_moving_global_elements_to_the_same_module(self):
+        self.mod1.write('def a_func():\n    pass\n')
+        self._move(self.mod1, self.mod1.read().index('a_func'), self.mod1)
+
+    def test_moving_used_imports_to_destination_module(self):
+        self.mod3.write('a_var = 10')
+        code = 'import mod3\n' \
+               'from mod3 import a_var\n' \
+               'def a_func():\n' \
+               '    print(mod3, a_var)\n'
+        self.mod1.write(code)
+        self._move(self.mod1, code.index('a_func') + 1, self.mod2)
+        expected = 'import mod3\n' \
+                   'from mod3 import a_var\n\n\n' \
+                   'def a_func():\n    print(mod3, a_var)\n'
+        self.assertEquals(expected, self.mod2.read())
+
+    def test_moving_used_names_to_destination_module2(self):
+        code = 'a_var = 10\n' \
+               'def a_func():\n' \
+               '    print(a_var)\n'
+        self.mod1.write(code)
+        self._move(self.mod1, code.index('a_func') + 1, self.mod2)
+        self.assertEquals('a_var = 10\n', self.mod1.read())
+        expected = 'from mod1 import a_var\n\n\n' \
+                   'def a_func():\n' \
+                   '    print(a_var)\n'
+        self.assertEquals(expected, self.mod2.read())
+
+    def test_moving_used_underlined_names_to_destination_module(self):
+        code = '_var = 10\n' \
+               'def a_func():\n' \
+               '    print(_var)\n'
+        self.mod1.write(code)
+        self._move(self.mod1, code.index('a_func') + 1, self.mod2)
+        expected = 'from mod1 import _var\n\n\n' \
+                   'def a_func():\n' \
+                   '    print(_var)\n'
+        self.assertEquals(expected, self.mod2.read())
+
+    def test_moving_and_used_relative_imports(self):
+        code = 'import mod5\n' \
+               'def a_func():\n' \
+               '    print(mod5)\n'
+        self.mod4.write(code)
+        self._move(self.mod4, code.index('a_func') + 1, self.mod1)
+        expected = 'import pkg.mod5\n\n\n' \
+                   'def a_func():\n' \
+                   '    print(pkg.mod5)\n'
+        self.assertEquals(expected, self.mod1.read())
+
+    def test_moving_modules(self):
+        code = 'import mod1\nprint(mod1)'
+        self.mod2.write(code)
+        self._move(self.mod2, code.index('mod1') + 1, self.pkg)
+        expected = 'import pkg.mod1\nprint(pkg.mod1)'
+        self.assertEquals(expected, self.mod2.read())
+        self.assertTrue(not self.mod1.exists() and
+                        self.pycore.find_module('pkg.mod1') is not None)
+
+    def test_moving_modules_and_removing_out_of_date_imports(self):
+        code = 'import pkg.mod4\nprint(pkg.mod4)'
+        self.mod2.write(code)
+        self._move(self.mod2, code.index('mod4') + 1, self.project.root)
+        expected = 'import mod4\nprint(mod4)'
+        self.assertEquals(expected, self.mod2.read())
+        self.assertTrue(self.pycore.find_module('mod4') is not None)
+
+    def test_moving_modules_and_removing_out_of_date_froms(self):
+        code = 'from pkg import mod4\nprint(mod4)'
+        self.mod2.write(code)
+        self._move(self.mod2, code.index('mod4') + 1, self.project.root)
+        self.assertEquals('import mod4\nprint(mod4)', self.mod2.read())
+
+    def test_moving_modules_and_removing_out_of_date_froms2(self):
+        self.mod4.write('a_var = 10')
+        code = 'from pkg.mod4 import a_var\nprint(a_var)\n'
+        self.mod2.write(code)
+        self._move(self.mod2, code.index('mod4') + 1, self.project.root)
+        expected = 'from mod4 import a_var\nprint(a_var)\n'
+        self.assertEquals(expected, self.mod2.read())
+
+    def test_moving_modules_and_relative_import(self):
+        self.mod4.write('import mod5\nprint(mod5)\n')
+        code = 'import pkg.mod4\nprint(pkg.mod4)'
+        self.mod2.write(code)
+        self._move(self.mod2, code.index('mod4') + 1, self.project.root)
+        moved = self.pycore.find_module('mod4')
+        expected = 'import pkg.mod5\nprint(pkg.mod5)\n'
+        self.assertEquals(expected, moved.read())
+
+    def test_moving_packages(self):
+        pkg2 = testutils.create_package(self.project, 'pkg2')
+        code = 'import pkg.mod4\nprint(pkg.mod4)'
+        self.mod1.write(code)
+        self._move(self.mod1, code.index('pkg') + 1, pkg2)
+        self.assertFalse(self.pkg.exists())
+        self.assertTrue(self.pycore.find_module('pkg2.pkg.mod4') is not None)
+        self.assertTrue(self.pycore.find_module('pkg2.pkg.mod4') is not None)
+        self.assertTrue(self.pycore.find_module('pkg2.pkg.mod5') is not None)
+        expected = 'import pkg2.pkg.mod4\nprint(pkg2.pkg.mod4)'
+        self.assertEquals(expected, self.mod1.read())
+
+    def test_moving_modules_with_self_imports(self):
+        self.mod1.write('import mod1\nprint(mod1)\n')
+        self.mod2.write('import mod1\n')
+        self._move(self.mod2, self.mod2.read().index('mod1') + 1, self.pkg)
+        moved = self.pycore.find_module('pkg.mod1')
+        self.assertEquals('import pkg.mod1\nprint(pkg.mod1)\n', moved.read())
+
+    def test_moving_funtions_to_imported_module(self):
+        code = 'import mod1\n' \
+               'def a_func():\n' \
+               '    var = mod1.a_var\n'
+        self.mod1.write('a_var = 1\n')
+        self.mod2.write(code)
+        self._move(self.mod2, code.index('a_func') + 1, self.mod1)
+        expected = 'def a_func():\n' \
+                   '    var = a_var\n' \
+                   'a_var = 1\n'
+        self.assertEquals(expected, self.mod1.read())
+
+    def test_moving_resources_using_move_module_refactoring(self):
+        self.mod1.write('a_var = 1')
+        self.mod2.write('import mod1\nmy_var = mod1.a_var\n')
+        mover = move.create_move(self.project, self.mod1)
+        mover.get_changes(self.pkg).do()
+        expected = 'import pkg.mod1\nmy_var = pkg.mod1.a_var\n'
+        self.assertEquals(expected, self.mod2.read())
+        self.assertTrue(self.pkg.get_child('mod1.py') is not None)
+
+    def test_moving_resources_using_move_module_for_packages(self):
+        self.mod1.write('import pkg\nmy_pkg = pkg')
+        pkg2 = testutils.create_package(self.project, 'pkg2')
+        mover = move.create_move(self.project, self.pkg)
+        mover.get_changes(pkg2).do()
+        expected = 'import pkg2.pkg\nmy_pkg = pkg2.pkg'
+        self.assertEquals(expected, self.mod1.read())
+        self.assertTrue(pkg2.get_child('pkg') is not None)
+
+    def test_moving_resources_using_move_module_for_init_dot_py(self):
+        self.mod1.write('import pkg\nmy_pkg = pkg')
+        pkg2 = testutils.create_package(self.project, 'pkg2')
+        init = self.pkg.get_child('__init__.py')
+        mover = move.create_move(self.project, init)
+        mover.get_changes(pkg2).do()
+        self.assertEquals('import pkg2.pkg\nmy_pkg = pkg2.pkg',
+                          self.mod1.read())
+        self.assertTrue(pkg2.get_child('pkg') is not None)
+
+    def test_moving_module_and_star_imports(self):
+        self.mod1.write('a_var = 1')
+        self.mod2.write('from mod1 import *\na = a_var\n')
+        mover = move.create_move(self.project, self.mod1)
+        mover.get_changes(self.pkg).do()
+        self.assertEquals('from pkg.mod1 import *\na = a_var\n',
+                          self.mod2.read())
+
+    def test_moving_module_and_not_removing_blanks_after_imports(self):
+        self.mod4.write('a_var = 1')
+        self.mod2.write('from pkg import mod4\n'
+                        'import os\n\n\nprint(mod4.a_var)\n')
+        mover = move.create_move(self.project, self.mod4)
+        mover.get_changes(self.project.root).do()
+        self.assertEquals('import os\nimport mod4\n\n\n'
+                          'print(mod4.a_var)\n', self.mod2.read())
+
+    @testutils.assert_raises(exceptions.RefactoringError)
+    def test_moving_module_refactoring_and_nonexistent_destinations(self):
+        self.mod4.write('a_var = 1')
+        self.mod2.write('from pkg import mod4\n'
+                        'import os\n\n\nprint(mod4.a_var)\n')
+        mover = move.create_move(self.project, self.mod4)
+        mover.get_changes(None).do()
+
+    def test_moving_methods_choosing_the_correct_class(self):
+        code = 'class A(object):\n    def a_method(self):\n        pass\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1, code.index('a_method'))
+        self.assertTrue(isinstance(mover, move.MoveMethod))
+
+    def test_moving_methods_getting_new_method_for_empty_methods(self):
+        code = 'class A(object):\n    def a_method(self):\n        pass\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        self.assertEquals('def new_method(self):\n    pass\n',
+                          mover.get_new_method('new_method'))
+
+    def test_moving_methods_getting_new_method_for_constant_methods(self):
+        code = 'class A(object):\n    def a_method(self):\n        return 1\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        self.assertEquals('def new_method(self):\n    return 1\n',
+                          mover.get_new_method('new_method'))
+
+    def test_moving_methods_getting_new_method_passing_simple_paremters(self):
+        code = 'class A(object):\n' \
+               '    def a_method(self, p):\n        return p\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        self.assertEquals('def new_method(self, p):\n    return p\n',
+                          mover.get_new_method('new_method'))
+
+    def test_moving_methods_getting_new_method_using_main_object(self):
+        code = 'class A(object):\n    attr = 1\n' \
+               '    def a_method(host):\n        return host.attr\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        self.assertEquals('def new_method(self, host):\n    return host.attr\n',
+                          mover.get_new_method('new_method'))
+
+    def test_moving_methods_getting_new_method_renaming_main_object(self):
+        code = 'class A(object):\n    attr = 1\n' \
+               '    def a_method(self):\n        return self.attr\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        self.assertEquals('def new_method(self, host):\n    return host.attr\n',
+                          mover.get_new_method('new_method'))
+
+    def test_moving_methods_gettin_new_method_with_keyword_arguments(self):
+        code = 'class A(object):\n    attr = 1\n' \
+               '    def a_method(self, p=None):\n        return p\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        self.assertEquals('def new_method(self, p=None):\n    return p\n',
+                          mover.get_new_method('new_method'))
+
+    def test_moving_methods_gettin_new_method_with_many_kinds_arguments(self):
+        code = 'class A(object):\n    attr = 1\n' \
+               '    def a_method(self, p1, *args, **kwds):\n' \
+               '        return self.attr\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        expected = 'def new_method(self, host, p1, *args, **kwds):\n' \
+                   '    return host.attr\n'
+        self.assertEquals(expected, mover.get_new_method('new_method'))
+
+    def test_moving_methods_getting_new_method_for_multi_line_methods(self):
+        code = 'class A(object):\n' \
+               '    def a_method(self):\n' \
+               '        a = 2\n' \
+               '        return a\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        self.assertEquals(
+            'def new_method(self):\n    a = 2\n    return a\n',
+            mover.get_new_method('new_method'))
+
+    def test_moving_methods_getting_old_method_for_constant_methods(self):
+        self.mod2.write('class B(object):\n    pass\n')
+        code = 'import mod2\n\n' \
+               'class A(object):\n' \
+               '    attr = mod2.B()\n' \
+               '    def a_method(self):\n' \
+               '        return 1\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        mover.get_changes('attr', 'new_method').do()
+        expected = 'import mod2\n\n' \
+                   'class A(object):\n' \
+                   '    attr = mod2.B()\n' \
+                   '    def a_method(self):\n' \
+                   '        return self.attr.new_method()\n'
+        self.assertEquals(expected, self.mod1.read())
+
+    def test_moving_methods_getting_getting_changes_for_goal_class(self):
+        self.mod2.write('class B(object):\n    var = 1\n')
+        code = 'import mod2\n\n' \
+               'class A(object):\n' \
+               '    attr = mod2.B()\n' \
+               '    def a_method(self):\n' \
+               '        return 1\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        mover.get_changes('attr', 'new_method').do()
+        expected = 'class B(object):\n' \
+                   '    var = 1\n\n\n' \
+                   '    def new_method(self):\n' \
+                   '        return 1\n'
+        self.assertEquals(expected, self.mod2.read())
+
+    def test_moving_methods_getting_getting_changes_for_goal_class2(self):
+        code = 'class B(object):\n    var = 1\n\n' \
+               'class A(object):\n    attr = B()\n' \
+               '    def a_method(self):\n        return 1\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        mover.get_changes('attr', 'new_method').do()
+        self.assertEquals(
+            'class B(object):\n    var = 1\n\n\n'
+            '    def new_method(self):\n'
+            '        return 1\n\n'
+            'class A(object):\n    attr = B()\n'
+            '    def a_method(self):\n'
+            '        return self.attr.new_method()\n',
+            self.mod1.read())
+
+    @testutils.assert_raises(exceptions.RefactoringError)
+    def test_moving_methods_and_nonexistent_attributes(self):
+        code = 'class A(object):\n' \
+               '    def a_method(self):\n        return 1\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        mover.get_changes('x', 'new_method')
+
+    @testutils.assert_raises(exceptions.RefactoringError)
+    def test_unknown_attribute_type(self):
+        code = 'class A(object):\n    attr = 1\n' \
+               '    def a_method(self):\n        return 1\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        mover.get_changes('attr', 'new_method')
+
+    def test_moving_methods_and_moving_used_imports(self):
+        self.mod2.write('class B(object):\n    var = 1\n')
+        code = 'import sys\nimport mod2\n\n' \
+               'class A(object):\n' \
+               '    attr = mod2.B()\n' \
+               '    def a_method(self):\n' \
+               '        return sys.version\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        mover.get_changes('attr', 'new_method').do()
+        code = 'import sys\n' \
+               'class B(object):\n' \
+               '    var = 1\n\n\n' \
+               '    def new_method(self):\n' \
+               '        return sys.version\n'
+        self.assertEquals(code, self.mod2.read())
+
+    def test_moving_methods_getting_getting_changes_for_goal_class3(self):
+        self.mod2.write('class B(object):\n    pass\n')
+        code = 'import mod2\n\n' \
+               'class A(object):\n' \
+               '    attr = mod2.B()\n' \
+               '    def a_method(self):\n' \
+               '        return 1\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        mover.get_changes('attr', 'new_method').do()
+        expected = 'class B(object):\n\n' \
+                   '    def new_method(self):\n' \
+                   '        return 1\n'
+        self.assertEquals(expected, self.mod2.read())
+
+    def test_moving_methods_and_source_class_with_parameters(self):
+        self.mod2.write('class B(object):\n    pass\n')
+        code = 'import mod2\n\n' \
+               'class A(object):\n' \
+               '    attr = mod2.B()\n' \
+               '    def a_method(self, p):\n        return p\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('a_method'))
+        mover.get_changes('attr', 'new_method').do()
+        expected1 = 'import mod2\n\n' \
+                    'class A(object):\n' \
+                    '    attr = mod2.B()\n' \
+                    '    def a_method(self, p):\n' \
+                    '        return self.attr.new_method(p)\n'
+        self.assertEquals(expected1, self.mod1.read())
+        expected2 = 'class B(object):\n\n' \
+                    '    def new_method(self, p):\n' \
+                    '        return p\n'
+        self.assertEquals(expected2, self.mod2.read())
+
+    def test_moving_globals_to_a_module_with_only_docstrings(self):
+        self.mod1.write('import sys\n\n\ndef f():\n    print(sys.version)\n')
+        self.mod2.write('"""doc\n\nMore docs ...\n\n"""\n')
+        mover = move.create_move(self.project, self.mod1,
+                                 self.mod1.read().index('f()') + 1)
+        self.project.do(mover.get_changes(self.mod2))
+        self.assertEquals(
+            '"""doc\n\nMore docs ...\n\n"""\n'
+            'import sys\n\n\ndef f():\n    print(sys.version)\n',
+            self.mod2.read())
+
+    def test_moving_globals_to_a_module_with_only_docstrings2(self):
+        code = 'import os\n' \
+               'import sys\n\n\n' \
+               'def f():\n' \
+               '    print(sys.version, os.path)\n'
+        self.mod1.write(code)
+        self.mod2.write('"""doc\n\nMore docs ...\n\n"""\n')
+        mover = move.create_move(self.project, self.mod1,
+                                 self.mod1.read().index('f()') + 1)
+        self.project.do(mover.get_changes(self.mod2))
+        expected = '"""doc\n\nMore docs ...\n\n"""\n' \
+                   'import os\n' \
+                   'import sys\n\n\n' \
+                   'def f():\n' \
+                   '    print(sys.version, os.path)\n'
+        self.assertEquals(expected, self.mod2.read())
+
+    def test_moving_a_global_when_it_is_used_after_a_multiline_str(self):
+        code = 'def f():\n    pass\ns = """\\\n"""\nr = f()\n'
+        self.mod1.write(code)
+        mover = move.create_move(self.project, self.mod1,
+                                 code.index('f()') + 1)
+        self.project.do(mover.get_changes(self.mod2))
+        expected = 'import mod2\ns = """\\\n"""\nr = mod2.f()\n'
+        self.assertEquals(expected, self.mod1.read())
+
+    @testutils.assert_raises(exceptions.RefactoringError)
+    def test_raising_an_exception_when_moving_non_package_folders(self):
+        dir = self.project.root.create_folder('dir')
+        mover = move.create_move(self.project, dir)
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/refactor/multiprojecttest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,72 @@
+import unittest
+
+import rope.base.codeanalyze
+import rope.refactor.occurrences
+from rope.refactor import multiproject, rename, move
+from ropetest import testutils
+
+
+class MultiProjectRefactoringTest(unittest.TestCase):
+
+    def setUp(self):
+        super(MultiProjectRefactoringTest, self).setUp()
+        self.project1 = testutils.sample_project(foldername='testproject1')
+        self.project2 = testutils.sample_project(foldername='testproject2')
+        self.mod1 = self.project1.root.create_file('mod1.py')
+        self.other = self.project1.root.create_file('other.py')
+        self.mod2 = self.project2.root.create_file('mod2.py')
+
+    def tearDown(self):
+        testutils.remove_project(self.project1)
+        testutils.remove_project(self.project2)
+        super(MultiProjectRefactoringTest, self).tearDown()
+
+    def test_trivial_rename(self):
+        self.mod1.write('var = 1\n')
+        refactoring = multiproject.MultiProjectRefactoring(
+            rename.Rename, [])
+        renamer = refactoring(self.project1, self.mod1, 1)
+        multiproject.perform(renamer.get_all_changes('newvar'))
+        self.assertEquals('newvar = 1\n', self.mod1.read())
+
+    def test_rename(self):
+        self.mod1.write('var = 1\n')
+        self.mod2.write('import mod1\nmyvar = mod1.var\n')
+        refactoring = multiproject.MultiProjectRefactoring(
+            rename.Rename, [self.project2])
+        renamer = refactoring(self.project1, self.mod1, 1)
+        multiproject.perform(renamer.get_all_changes('newvar'))
+        self.assertEquals('newvar = 1\n', self.mod1.read())
+        self.assertEquals('import mod1\nmyvar = mod1.newvar\n',
+                          self.mod2.read())
+
+    def test_move(self):
+        self.mod1.write('def a_func():\n    pass\n')
+        self.mod2.write('import mod1\nmyvar = mod1.a_func()\n')
+        refactoring = multiproject.MultiProjectRefactoring(
+            move.create_move, [self.project2])
+        renamer = refactoring(self.project1, self.mod1,
+                              self.mod1.read().index('_func'))
+        multiproject.perform(renamer.get_all_changes(self.other))
+        self.assertEquals('', self.mod1.read())
+        self.assertEquals('def a_func():\n    pass\n', self.other.read())
+        self.assertEquals(
+            'import mod1\nimport other\nmyvar = other.a_func()\n',
+            self.mod2.read())
+
+    def test_rename_from_the_project_not_containing_the_change(self):
+        self.project2.get_prefs().add('python_path', self.project1.address)
+        self.mod1.write('var = 1\n')
+        self.mod2.write('import mod1\nmyvar = mod1.var\n')
+        refactoring = multiproject.MultiProjectRefactoring(
+            rename.Rename, [self.project1])
+        renamer = refactoring(self.project2, self.mod2,
+                              self.mod2.read().rindex('var'))
+        multiproject.perform(renamer.get_all_changes('newvar'))
+        self.assertEquals('newvar = 1\n', self.mod1.read())
+        self.assertEquals('import mod1\nmyvar = mod1.newvar\n',
+                          self.mod2.read())
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/refactor/patchedasttest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,832 @@
+import unittest
+
+from rope.base import ast
+from rope.refactor import patchedast
+from ropetest import testutils
+
+
+class PatchedASTTest(unittest.TestCase):
+
+    def setUp(self):
+        super(PatchedASTTest, self).setUp()
+
+    def tearDown(self):
+        super(PatchedASTTest, self).tearDown()
+
+    def test_integer_literals_and_region(self):
+        source = 'a = 10\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        start = source.index('10')
+        checker.check_region('Num', start, start + 2)
+
+    def test_integer_literals_and_sorted_children(self):
+        source = 'a = 10\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        start = source.index('10')
+        checker.check_children('Num', ['10'])
+
+    def test_ass_name_node(self):
+        source = 'a = 10\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        start = source.index('a')
+        checker.check_region('Name', start, start + 1)
+        checker.check_children('Name', ['a'])
+
+    def test_assign_node(self):
+        source = 'a = 10\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        start = source.index('a')
+        checker.check_region('Assign', 0, len(source) - 1)
+        checker.check_children(
+            'Assign', ['Name', ' ', '=', ' ', 'Num'])
+
+    def test_add_node(self):
+        source = '1 + 2\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('BinOp', 0, len(source) - 1)
+        checker.check_children(
+            'BinOp', ['Num', ' ', '+', ' ', 'Num'])
+
+    def test_lshift_node(self):
+        source = '1 << 2\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('BinOp', 0, len(source) - 1)
+        checker.check_children(
+            'BinOp', ['Num', ' ', '<<', ' ', 'Num'])
+
+    def test_and_node(self):
+        source = 'True and True\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('BoolOp', 0, len(source) - 1)
+        checker.check_children(
+            'BoolOp', ['Name', ' ', 'and', ' ', 'Name'])
+
+    def test_basic_closing_parens(self):
+        source = '1 + (2)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('BinOp', 0, len(source) - 1)
+        checker.check_children(
+            'BinOp', ['Num', ' ', '+', ' (', 'Num', ')'])
+
+    def test_basic_opening_parens(self):
+        source = '(1) + 2\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('BinOp', 0, len(source) - 1)
+        checker.check_children(
+            'BinOp', ['(', 'Num', ') ', '+', ' ', 'Num'])
+
+    def test_basic_opening_biway(self):
+        source = '(1) + (2)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('BinOp', 0, len(source) - 1)
+        checker.check_children(
+            'BinOp', ['(', 'Num', ') ', '+', ' (', 'Num', ')'])
+
+    def test_basic_opening_double(self):
+        source = '1 + ((2))\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('BinOp', 0, len(source) - 1)
+        checker.check_children(
+            'BinOp', ['Num', ' ', '+', ' ((', 'Num', '))'])
+
+    def test_handling_comments(self):
+        source = '(1 + #(\n2)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'BinOp', ['Num', ' ', '+', ' #(\n', 'Num'])
+
+    def test_handling_parens_with_spaces(self):
+        source = '1 + (2\n    )\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'BinOp', ['Num', ' ', '+', ' (', 'Num', '\n    )'])
+
+    def test_handling_strings(self):
+        source = '1 + "("\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'BinOp', ['Num', ' ', '+', ' ', 'Str'])
+
+    def test_handling_implicit_string_concatenation(self):
+        source = "a = '1''2'"
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'Assign', ['Name' , ' ', '=', ' ', 'Str'])
+        checker.check_children('Str', ["'1''2'"])
+
+    def test_handling_implicit_string_concatenation_line_breaks(self):
+        source = "a = '1' \\\n'2'"
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'Assign', ['Name' , ' ', '=', ' ', 'Str'])
+        checker.check_children('Str', ["'1' \\\n'2'"])
+
+    def test_handling_explicit_string_concatenation_line_breaks(self):
+        source = "a = ('1' \n'2')"
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'Assign', ['Name' , ' ', '=', ' (', 'Str', ')'])
+        checker.check_children('Str', ["'1' \n'2'"])
+
+    def test_not_concatenating_strings_on_separate_lines(self):
+        source = "'1'\n'2'\n"
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children('Module', ['', 'Expr', '\n', 'Expr', '\n'])
+
+    def test_long_integer_literals(self):
+        source = "0x1L + a"
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'BinOp', ['Num' , ' ', '+', ' ', 'Name'])
+        checker.check_children('Num', ['0x1L'])
+
+    def test_complex_number_literals(self):
+        source = "1.0e2j + a"
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'BinOp', ['Num' , ' ', '+', ' ', 'Name'])
+        checker.check_children('Num', ['1.0e2j'])
+
+    def test_ass_attr_node(self):
+        source = 'a.b = 1\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Attribute', 0, source.index('=') - 1)
+        checker.check_children('Attribute', ['Name', '', '.', '', 'b'])
+
+    def test_ass_list_node(self):
+        source = '[a, b] = 1, 2\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('List', 0, source.index(']') + 1)
+        checker.check_children('List', ['[', '', 'Name', '', ',',
+                                        ' ', 'Name', '', ']'])
+
+    def test_ass_tuple(self):
+        source = 'a, b = range(2)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Tuple', 0, source.index('=') - 1)
+        checker.check_children(
+            'Tuple', ['Name', '', ',', ' ', 'Name'])
+
+    def test_ass_tuple2(self):
+        source = '(a, b) = range(2)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Tuple', 0, source.index('=') - 1)
+        checker.check_children(
+            'Tuple', ['(', '', 'Name', '', ',', ' ', 'Name', '', ')'])
+
+    def test_assert(self):
+        source = 'assert True\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Assert', 0, len(source) - 1)
+        checker.check_children(
+            'Assert', ['assert', ' ', 'Name'])
+
+    def test_assert2(self):
+        source = 'assert True, "error"\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Assert', 0, len(source) - 1)
+        checker.check_children(
+            'Assert', ['assert', ' ', 'Name', '', ',', ' ', 'Str'])
+
+    def test_aug_assign_node(self):
+        source = 'a += 1\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        start = source.index('a')
+        checker.check_region('AugAssign', 0, len(source) - 1)
+        checker.check_children(
+            'AugAssign', ['Name', ' ', '+', '', '=', ' ', 'Num'])
+
+    def test_back_quotenode(self):
+        source = '`1`\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Repr', 0, len(source) - 1)
+        checker.check_children(
+            'Repr', ['`', '', 'Num', '', '`'])
+
+    def test_bitand(self):
+        source = '1 & 2\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('BinOp', 0, len(source) - 1)
+        checker.check_children(
+            'BinOp', ['Num', ' ', '&', ' ', 'Num'])
+
+    def test_bitor(self):
+        source = '1 | 2\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'BinOp', ['Num', ' ', '|', ' ', 'Num'])
+
+    def test_call_func(self):
+        source = 'f(1, 2)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Call', 0, len(source) - 1)
+        checker.check_children(
+            'Call', ['Name', '', '(', '', 'Num', '', ',',
+                     ' ', 'Num', '', ')'])
+
+    def test_call_func_and_keywords(self):
+        source = 'f(1, p=2)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'Call', ['Name', '', '(', '', 'Num', '', ',',
+                     ' ', 'keyword', '', ')'])
+
+    def test_call_func_and_start_args(self):
+        source = 'f(1, *args)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'Call', ['Name', '', '(', '', 'Num', '', ',',
+                     ' ', '*', '', 'Name', '', ')'])
+
+    def test_call_func_and_only_dstart_args(self):
+        source = 'f(**kwds)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'Call', ['Name', '', '(', '', '**', '', 'Name', '', ')'])
+
+    def test_call_func_and_both_varargs_and_kwargs(self):
+        source = 'f(*args, **kwds)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'Call', ['Name', '', '(', '', '*', '', 'Name', '', ',',
+                     ' ', '**', '', 'Name', '', ')'])
+
+    def test_class_node(self):
+        source = 'class A(object):\n    """class docs"""\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Class', 0, len(source) - 1)
+        checker.check_children(
+            'Class', ['class', ' ', 'A', '', '(', '', 'Name', '', ')',
+                      '', ':', '\n    ', 'Expr', '\n    ', 'Pass'])
+
+    def test_class_with_no_bases(self):
+        source = 'class A:\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Class', 0, len(source) - 1)
+        checker.check_children(
+            'Class', ['class', ' ', 'A', '', ':', '\n    ', 'Pass'])
+
+    def test_simple_compare(self):
+        source = '1 < 2\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Compare', 0, len(source) - 1)
+        checker.check_children(
+            'Compare', ['Num', ' ', '<', ' ', 'Num'])
+
+    def test_multiple_compare(self):
+        source = '1 < 2 <= 3\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Compare', 0, len(source) - 1)
+        checker.check_children(
+            'Compare', ['Num', ' ', '<', ' ', 'Num', ' ',
+                        '<=', ' ', 'Num'])
+
+    def test_decorators_node(self):
+        source = '@d\ndef f():\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('FunctionDef', 0, len(source) - 1)
+        checker.check_children(
+            'FunctionDef',
+            ['@', '', 'Name', '\n', 'def', ' ', 'f', '', '(', '', 'arguments',
+             '', ')', '', ':', '\n    ', 'Pass'])
+
+    @testutils.only_for('2.6')
+    def test_decorators_for_classes(self):
+        source = '@d\nclass C(object):\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('ClassDef', 0, len(source) - 1)
+        checker.check_children(
+            'ClassDef',
+            ['@', '', 'Name', '\n', 'class', ' ', 'C', '', '(', '', 'Name',
+             '', ')', '', ':', '\n    ', 'Pass'])
+
+    def test_both_varargs_and_kwargs(self):
+        source = 'def f(*args, **kwds):\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'arguments', ['*', '', 'args' , '', ',' , ' ', '**', '', 'kwds'])
+
+    def test_function_node(self):
+        source = 'def f():\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Function', 0, len(source) - 1)
+        checker.check_children('Function', ['def', ' ', 'f', '', '(', '', 'arguments', '',
+                                            ')', '', ':', '\n    ', 'Pass'])
+
+    def test_function_node2(self):
+        source = 'def f(p1, **p2):\n    """docs"""\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Function', 0, len(source) - 1)
+        checker.check_children(
+            'Function', ['def', ' ', 'f', '', '(', '', 'arguments',
+                         '', ')' , '', ':', '\n    ', 'Expr', '\n    ', 'Pass'])
+        checker.check_children(
+            'arguments', ['Name', '', ',',
+                          ' ', '**', '', 'p2'])
+
+    def test_function_node_and_tuple_parameters(self):
+        source = 'def f(a, (b, c)):\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Function', 0, len(source) - 1)
+        checker.check_children(
+            'Function', ['def', ' ', 'f', '', '(', '', 'arguments',
+                         '', ')' , '', ':', '\n    ', 'Pass'])
+        checker.check_children(
+            'arguments', ['Name', '', ',', ' ', 'Tuple'])
+
+    def test_dict_node(self):
+        source = '{1: 2, 3: 4}\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Dict', 0, len(source) - 1)
+        checker.check_children(
+            'Dict', ['{', '', 'Num', '', ':', ' ', 'Num', '', ',',
+                     ' ', 'Num', '', ':', ' ', 'Num', '', '}'])
+
+    def test_div_node(self):
+        source = '1 / 2\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('BinOp', 0, len(source) - 1)
+        checker.check_children('BinOp', ['Num', ' ', '/', ' ', 'Num'])
+
+    def test_simple_exec_node(self):
+        source = 'exec ""\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Exec', 0, len(source) - 1)
+        checker.check_children('Exec', ['exec', ' ', 'Str'])
+
+    def test_exec_node(self):
+        source = 'exec "" in locals(), globals()\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Exec', 0, len(source) - 1)
+        checker.check_children(
+            'Exec', ['exec', ' ', 'Str', ' ', 'in',
+                     ' ', 'Call', '', ',', ' ', 'Call'])
+
+    def test_for_node(self):
+        source = 'for i in range(1):\n    pass\nelse:\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('For', 0, len(source) - 1)
+        checker.check_children(
+            'For', ['for', ' ', 'Name', ' ', 'in', ' ', 'Call', '',
+                    ':', '\n    ', 'Pass', '\n',
+                    'else', '', ':', '\n    ', 'Pass'])
+
+    def test_normal_from_node(self):
+        source = 'from x import y\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('ImportFrom', 0, len(source) - 1)
+        checker.check_children(
+            'ImportFrom', ['from', ' ', 'x', ' ', 'import', ' ', 'alias'])
+        checker.check_children('alias', ['y'])
+
+    @testutils.run_only_for_25
+    def test_from_node(self):
+        source = 'from ..x import y as z\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('ImportFrom', 0, len(source) - 1)
+        checker.check_children(
+            'ImportFrom', ['from', ' ', '..', '', 'x', ' ',
+                           'import', ' ', 'alias'])
+        checker.check_children('alias', ['y', ' ', 'as', ' ', 'z'])
+
+    def test_simple_gen_expr_node(self):
+        source = 'zip(i for i in x)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('GeneratorExp', 4, len(source) - 2)
+        checker.check_children(
+            'GeneratorExp', ['Name', ' ', 'comprehension'])
+        checker.check_children(
+            'comprehension', ['for', ' ', 'Name', ' ', 'in', ' ', 'Name'])
+
+    def test_gen_expr_node_handling_surrounding_parens(self):
+        source = '(i for i in x)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('GeneratorExp', 0, len(source) - 1)
+        checker.check_children(
+            'GeneratorExp', ['(', '', 'Name', ' ', 'comprehension', '', ')'])
+
+    def test_gen_expr_node2(self):
+        source = 'zip(i for i in range(1) if i == 1)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'comprehension', ['for', ' ', 'Name', ' ', 'in', ' ', 'Call',
+                              ' ', 'if', ' ', 'Compare'])
+
+    def test_get_attr_node(self):
+        source = 'a.b\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Attribute', 0, len(source) - 1)
+        checker.check_children('Attribute', ['Name', '', '.', '', 'b'])
+
+    def test_global_node(self):
+        source = 'global a, b\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Global', 0, len(source) - 1)
+        checker.check_children('Global', ['global', ' ', 'a', '', ',', ' ', 'b'])
+
+    def test_if_node(self):
+        source = 'if True:\n    pass\nelse:\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('If', 0, len(source) - 1)
+        checker.check_children(
+            'If', ['if', ' ', 'Name', '', ':', '\n    ', 'Pass', '\n',
+                   'else', '', ':', '\n    ', 'Pass'])
+
+    def test_if_node2(self):
+        source = 'if True:\n    pass\nelif False:\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('If', 0, len(source) - 1)
+        checker.check_children(
+            'If', ['if', ' ', 'Name', '', ':', '\n    ', 'Pass', '\n',
+                   'If'])
+
+    def test_if_node3(self):
+        source = 'if True:\n    pass\nelse:\n' \
+                 '    if True:\n        pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('If', 0, len(source) - 1)
+        checker.check_children(
+            'If', ['if', ' ', 'Name', '', ':', '\n    ', 'Pass', '\n',
+                   'else', '', ':', '\n    ', 'If'])
+
+    def test_import_node(self):
+        source = 'import a, b as c\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Import', 0, len(source) - 1)
+        checker.check_children(
+            'Import', ['import', ' ', 'alias', '', ',', ' ', 'alias'])
+
+    def test_lambda_node(self):
+        source = 'lambda a, b=1, *z: None\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Lambda', 0, len(source) - 1)
+        checker.check_children(
+            'Lambda', ['lambda', ' ', 'arguments', '', ':', ' ', 'Name'])
+        checker.check_children(
+            'arguments', ['Name', '', ',', ' ', 'Name', '', '=', '',
+                          'Num', '', ',', ' ', '*', '', 'z'])
+
+    def test_list_node(self):
+        source = '[1, 2]\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('List', 0, len(source) - 1)
+        checker.check_children(
+            'List', ['[', '', 'Num', '', ',', ' ', 'Num', '', ']'])
+
+    def test_list_comp_node(self):
+        source = '[i for i in range(1) if True]\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('ListComp', 0, len(source) - 1)
+        checker.check_children(
+            'ListComp', ['[', '', 'Name', ' ', 'comprehension', '', ']'])
+        checker.check_children(
+            'comprehension', ['for', ' ', 'Name', ' ', 'in', ' ',
+                              'Call', ' ', 'if', ' ', 'Name'])
+
+    def test_list_comp_node_with_multiple_comprehensions(self):
+        source = '[i for i in range(1) for j in range(1) if True]\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('ListComp', 0, len(source) - 1)
+        checker.check_children(
+            'ListComp', ['[', '', 'Name', ' ', 'comprehension',
+                         ' ', 'comprehension', '', ']'])
+        checker.check_children(
+            'comprehension', ['for', ' ', 'Name', ' ', 'in', ' ',
+                              'Call', ' ', 'if', ' ', 'Name'])
+
+    def test_ext_slice_node(self):
+        source = 'x = xs[0,:]\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('ExtSlice', 7, len(source) - 2)
+        checker.check_children('ExtSlice', ['Index', '', ',', '', 'Slice'])
+
+    def test_simple_module_node(self):
+        source = 'pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Module', 0, len(source))
+        checker.check_children('Module', ['', 'Pass', '\n'])
+
+    def test_module_node(self):
+        source = '"""docs"""\npass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Module', 0, len(source))
+        checker.check_children('Module', ['', 'Expr', '\n', 'Pass', '\n'])
+        checker.check_children('Str', ['"""docs"""'])
+
+    def test_not_and_or_nodes(self):
+        source = 'not True or False\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children('Expr', ['BoolOp'])
+        checker.check_children('BoolOp', ['UnaryOp', ' ', 'or', ' ', 'Name'])
+
+    def test_print_node(self):
+        source = 'print >>out, 1,\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Print', 0, len(source) - 1)
+        checker.check_children('Print', ['print', ' ', '>>', '', 'Name', '',
+                                         ',', ' ', 'Num', '', ','])
+
+    def test_printnl_node(self):
+        source = 'print 1\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Print', 0, len(source) - 1)
+        checker.check_children('Print', ['print', ' ', 'Num'])
+
+    def test_raise_node(self):
+        source = 'raise x, y, z\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_region('Raise', 0, len(source) - 1)
+        checker.check_children(
+            'Raise', ['raise', ' ', 'Name', '', ',', ' ', 'Name', '', ',',
+                      ' ', 'Name'])
+
+    def test_return_node(self):
+        source = 'def f():\n    return None\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children('Return', ['return', ' ', 'Name'])
+
+    def test_empty_return_node(self):
+        source = 'def f():\n    return\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children('Return', ['return'])
+
+    def test_simple_slice_node(self):
+        source = 'a[1:2]\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'Subscript', ['Name', '', '[', '', 'Slice', '', ']'])
+        checker.check_children(
+            'Slice', ['Num', '', ':', '', 'Num'])
+
+    def test_slice_node2(self):
+        source = 'a[:]\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children('Subscript', ['Name', '', '[', '', 'Slice', '', ']'])
+        checker.check_children('Slice', [':'])
+
+    def test_simple_subscript(self):
+        source = 'a[1]\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'Subscript', ['Name', '', '[', '', 'Index', '', ']'])
+        checker.check_children('Index', ['Num'])
+
+    def test_tuple_node(self):
+        source = '(1, 2)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'Tuple', ['(', '', 'Num', '', ',', ' ', 'Num', '', ')'])
+
+    def test_tuple_node2(self):
+        source = '#(\n1, 2\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children('Tuple', ['Num', '', ',', ' ', 'Num'])
+
+    def test_one_item_tuple_node(self):
+        source = '(1,)\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children('Tuple', ['(', '', 'Num', ',', ')'])
+
+    def test_empty_tuple_node(self):
+        source = '()\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children('Tuple', ['(', '', ')'])
+
+    def test_yield_node(self):
+        source = 'def f():\n    yield None\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children('Yield', ['yield', ' ', 'Name'])
+
+    def test_while_node(self):
+        source = 'while True:\n    pass\nelse:\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'While', ['while', ' ', 'Name', '', ':', '\n    ', 'Pass', '\n',
+                      'else', '', ':', '\n    ', 'Pass'])
+
+    @testutils.run_only_for_25
+    def test_with_node(self):
+        source = 'from __future__ import with_statement\nwith a as b:\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'With', ['with', ' ', 'Name', ' ', 'as', ' ', 'Name', '', ':',
+                     '\n    ', 'Pass'])
+
+    def test_try_finally_node(self):
+        source = 'try:\n    pass\nfinally:\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'TryFinally', ['try', '', ':', '\n    ', 'Pass', '\n', 'finally',
+                           '', ':', '\n    ', 'Pass'])
+
+    def test_try_except_node(self):
+        source = 'try:\n    pass\nexcept Exception, e:\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'TryExcept', ['try', '', ':', '\n    ', 'Pass', '\n',
+                          ('excepthandler', 'ExceptHandler')])
+        checker.check_children(
+            ('excepthandler', 'ExceptHandler'),
+            ['except', ' ', 'Name', '', ',', ' ', 'Name', '', ':',
+             '\n    ', 'Pass'])
+
+    @testutils.run_only_for_25
+    def test_try_except_and_finally_node(self):
+        source = 'try:\n    pass\nexcept:\n    pass\nfinally:\n    pass\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'TryFinally', ['TryExcept', '\n', 'finally',
+                           '', ':', '\n    ', 'Pass'])
+
+    def test_ignoring_comments(self):
+        source = '#1\n1\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        start = source.rindex('1')
+        checker.check_region('Num', start, start + 1)
+
+    def test_simple_sliceobj(self):
+        source = 'a[1::3]\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'Slice', ['Num', '', ':', '', ':', '', 'Num'])
+
+    def test_ignoring_strings_that_start_with_a_char(self):
+        source = 'r"""("""\n1\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'Module', ['', 'Expr', '\n', 'Expr', '\n'])
+
+    def test_how_to_handle_old_not_equals(self):
+        source = '1 <> 2\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'Compare', ['Num', ' ', '<>', ' ', 'Num'])
+
+    def test_semicolon(self):
+        source = '1;\n'
+        ast = patchedast.get_patched_ast(source, True)
+
+    @testutils.run_only_for_25
+    def test_if_exp_node(self):
+        source = '1 if True else 2\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'IfExp', ['Num', ' ', 'if', ' ', 'Name', ' ', 'else',
+                      ' ', 'Num'])
+
+    def test_delete_node(self):
+        source = 'del a, b\n'
+        ast = patchedast.get_patched_ast(source, True)
+        checker = _ResultChecker(self, ast)
+        checker.check_children(
+            'Delete', ['del', ' ', 'Name', '', ',', ' ', 'Name'])
+
+
+class _ResultChecker(object):
+
+    def __init__(self, test_case, ast):
+        self.test_case = test_case
+        self.ast = ast
+
+    def check_region(self, text, start, end):
+        node = self._find_node(text)
+        if node is None:
+            self.test_case.fail('Node <%s> cannot be found' % text)
+        self.test_case.assertEquals((start, end), node.region)
+
+    def _find_node(self, text):
+        goal = text
+        if not isinstance(text, (tuple, list)):
+            goal = [text]
+        class Search(object):
+            result = None
+            def __call__(self, node):
+                for text in goal:
+                    if str(node).startswith(text):
+                        self.result = node
+                        break
+                    if node.__class__.__name__.startswith(text):
+                        self.result = node
+                        break
+                return self.result is not None
+        search = Search()
+        ast.call_for_nodes(self.ast, search, recursive=True)
+        return search.result
+
+    def check_children(self, text, children):
+        node = self._find_node(text)
+        if node is None:
+            self.test_case.fail('Node <%s> cannot be found' % text)
+        result = list(node.sorted_children)
+        self.test_case.assertEquals(len(children), len(result))
+        for expected, child in zip(children, result):
+            goals = expected
+            if not isinstance(expected, (tuple, list)):
+                goals = [expected]
+            for goal in goals:
+                if goal == '' or isinstance(child, basestring):
+                    self.test_case.assertEquals(goal, child)
+                    break
+            else:
+                self.test_case.assertNotEquals(
+                    '', text, 'probably ignoring some node')
+                self.test_case.assertTrue(
+                    child.__class__.__name__.startswith(expected),
+                    msg='Expected <%s> but was <%s>' %
+                    (expected, child.__class__.__name__))
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/refactor/renametest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,676 @@
+import sys
+import unittest
+
+import rope.base.codeanalyze
+import rope.refactor.occurrences
+from rope.refactor import rename
+from rope.refactor.rename import Rename
+from ropetest import testutils
+
+
+class RenameRefactoringTest(unittest.TestCase):
+
+    def setUp(self):
+        super(RenameRefactoringTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(RenameRefactoringTest, self).tearDown()
+
+    def _local_rename(self, source_code, offset, new_name):
+        testmod = testutils.create_module(self.project, 'testmod')
+        testmod.write(source_code)
+        changes = Rename(self.project, testmod, offset).\
+            get_changes(new_name, resources=[testmod])
+        self.project.do(changes)
+        return testmod.read()
+
+    def _rename(self, resource, offset, new_name, **kwds):
+        changes = Rename(self.project, resource, offset).\
+                  get_changes(new_name, **kwds)
+        self.project.do(changes)
+
+    def test_simple_global_variable_renaming(self):
+        refactored = self._local_rename('a_var = 20\n', 2, 'new_var')
+        self.assertEquals('new_var = 20\n', refactored)
+
+    def test_variable_renaming_only_in_its_scope(self):
+        refactored = self._local_rename(
+            'a_var = 20\ndef a_func():\n    a_var = 10\n', 32, 'new_var')
+        self.assertEquals('a_var = 20\ndef a_func():\n    new_var = 10\n',
+                          refactored)
+
+    def test_not_renaming_dot_name(self):
+        refactored = self._local_rename(
+            "replace = True\n'aaa'.replace('a', 'b')\n", 1, 'new_var')
+        self.assertEquals("new_var = True\n'aaa'.replace('a', 'b')\n",
+                          refactored)
+
+    def test_renaming_multiple_names_in_the_same_line(self):
+        refactored = self._local_rename(
+            'a_var = 10\na_var = 10 + a_var / 2\n', 2, 'new_var')
+        self.assertEquals('new_var = 10\nnew_var = 10 + new_var / 2\n',
+                          refactored)
+
+    def test_renaming_names_when_getting_some_attribute(self):
+        refactored = self._local_rename(
+            "a_var = 'a b c'\na_var.split('\\n')\n", 2, 'new_var')
+        self.assertEquals("new_var = 'a b c'\nnew_var.split('\\n')\n",
+                          refactored)
+
+    def test_renaming_names_when_getting_some_attribute2(self):
+        refactored = self._local_rename(
+            "a_var = 'a b c'\na_var.split('\\n')\n", 20, 'new_var')
+        self.assertEquals("new_var = 'a b c'\nnew_var.split('\\n')\n",
+                          refactored)
+
+    def test_renaming_function_parameters1(self):
+        refactored = self._local_rename(
+            "def f(a_param):\n    print(a_param)\n", 8, 'new_param')
+        self.assertEquals("def f(new_param):\n    print(new_param)\n",
+                          refactored)
+
+    def test_renaming_function_parameters2(self):
+        refactored = self._local_rename(
+            "def f(a_param):\n    print(a_param)\n", 30, 'new_param')
+        self.assertEquals("def f(new_param):\n    print(new_param)\n",
+                          refactored)
+
+    def test_renaming_occurrences_inside_functions(self):
+        code = 'def a_func(p1):\n    a = p1\na_func(1)\n'
+        refactored = self._local_rename(code, code.index('p1') + 1, 'new_param')
+        self.assertEquals(
+            'def a_func(new_param):\n    a = new_param\na_func(1)\n', 
+            refactored)
+
+    def test_renaming_arguments_for_normal_args_changing_calls(self):
+        code = 'def a_func(p1=None, p2=None):\n    pass\na_func(p2=1)\n'
+        refactored = self._local_rename(code, code.index('p2') + 1, 'p3')
+        self.assertEquals(
+            'def a_func(p1=None, p3=None):\n    pass\na_func(p3=1)\n',
+            refactored)
+
+    def test_renaming_function_parameters_of_class_init(self):
+        code = 'class A(object):\n    def __init__(self, a_param):\n        pass\n' \
+               'a_var = A(a_param=1)\n'
+        refactored = self._local_rename(code, code.index('a_param') + 1, 'new_param')
+        expected = 'class A(object):\n    def __init__(self, new_param):\n        pass\n' \
+                   'a_var = A(new_param=1)\n'
+        self.assertEquals(expected, refactored)
+
+    def test_renaming_functions_parameters_and_occurances_in_other_modules(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('def a_func(a_param):\n    print(a_param)\n')
+        mod2.write('from mod1 import a_func\na_func(a_param=10)\n')
+        self._rename(mod1, mod1.read().index('a_param') + 1, 'new_param')
+        self.assertEquals('def a_func(new_param):\n    print(new_param)\n',
+                          mod1.read())
+        self.assertEquals('from mod1 import a_func\na_func(new_param=10)\n',
+                          mod2.read())
+
+    def test_renaming_with_backslash_continued_names(self):
+        refactored = self._local_rename(
+            "replace = True\n'ali'.\\\nreplace\n", 2, 'is_replace')
+        self.assertEquals("is_replace = True\n'ali'.\\\nreplace\n",
+                          refactored)
+
+    def test_not_renaming_string_contents(self):
+        refactored = self._local_rename("a_var = 20\na_string='a_var'\n",
+                                        2, 'new_var')
+        self.assertEquals("new_var = 20\na_string='a_var'\n",
+                          refactored)
+
+    def test_not_renaming_comment_contents(self):
+        refactored = self._local_rename("a_var = 20\n# a_var\n",
+                                        2, 'new_var')
+        self.assertEquals("new_var = 20\n# a_var\n", refactored)
+
+    def test_renaming_all_occurances_in_containing_scope(self):
+        code = 'if True:\n    a_var = 1\nelse:\n    a_var = 20\n'
+        refactored = self._local_rename(code, 16, 'new_var')
+        self.assertEquals(
+            'if True:\n    new_var = 1\nelse:\n    new_var = 20\n', refactored)
+
+    def test_renaming_a_variable_with_arguement_name(self):
+        code = 'a_var = 10\ndef a_func(a_var):\n    print(a_var)\n'
+        refactored = self._local_rename(code, 1, 'new_var')
+        self.assertEquals(
+            'new_var = 10\ndef a_func(a_var):\n    print(a_var)\n', refactored)
+
+    def test_renaming_an_arguement_with_variable_name(self):
+        code = 'a_var = 10\ndef a_func(a_var):\n    print(a_var)\n'
+        refactored = self._local_rename(code, len(code) - 3, 'new_var')
+        self.assertEquals(
+            'a_var = 10\ndef a_func(new_var):\n    print(new_var)\n',
+            refactored)
+
+    def test_renaming_function_with_local_variable_name(self):
+        code = 'def a_func():\n    a_func=20\na_func()'
+        refactored = self._local_rename(code, len(code) - 3, 'new_func')
+        self.assertEquals('def new_func():\n    a_func=20\nnew_func()',
+                          refactored)
+
+    def test_renaming_functions(self):
+        code = 'def a_func():\n    pass\na_func()\n'
+        refactored = self._local_rename(code, len(code) - 5, 'new_func')
+        self.assertEquals('def new_func():\n    pass\nnew_func()\n',
+                          refactored)
+
+    def test_renaming_functions_across_modules(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('def a_func():\n    pass\na_func()\n')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod2.write('import mod1\nmod1.a_func()\n')
+        self._rename(mod1, len(mod1.read()) - 5, 'new_func')
+        self.assertEquals('def new_func():\n    pass\nnew_func()\n',
+                          mod1.read())
+        self.assertEquals('import mod1\nmod1.new_func()\n', mod2.read())
+
+    def test_renaming_functions_across_modules_from_import(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('def a_func():\n    pass\na_func()\n')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod2.write('from mod1 import a_func\na_func()\n')
+        self._rename(mod1, len(mod1.read()) - 5, 'new_func')
+        self.assertEquals('def new_func():\n    pass\nnew_func()\n',
+                          mod1.read())
+        self.assertEquals('from mod1 import new_func\nnew_func()\n',
+                          mod2.read())
+
+    def test_renaming_functions_from_another_module(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('def a_func():\n    pass\na_func()\n')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod2.write('import mod1\nmod1.a_func()\n')
+        self._rename(mod2, len(mod2.read()) - 5, 'new_func')
+        self.assertEquals('def new_func():\n    pass\nnew_func()\n',
+                          mod1.read())
+        self.assertEquals('import mod1\nmod1.new_func()\n', mod2.read())
+
+    def test_applying_all_changes_together(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('import mod2\nmod2.a_func()\n')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod2.write('def a_func():\n    pass\na_func()\n')
+        self._rename(mod2, len(mod2.read()) - 5, 'new_func')
+        self.assertEquals('import mod2\nmod2.new_func()\n', mod1.read())
+        self.assertEquals('def new_func():\n    pass\nnew_func()\n',
+                          mod2.read())
+
+    def test_renaming_modules(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('def a_func():\n    pass\n')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod2.write('from mod1 import a_func\n')
+        self._rename(mod2, mod2.read().index('mod1') + 1, 'newmod')
+        self.assertTrue(not mod1.exists() and
+                        self.pycore.find_module('newmod') is not None)
+        self.assertEquals('from newmod import a_func\n', mod2.read())
+
+    def test_renaming_packages(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1 = testutils.create_module(self.project, 'mod1', pkg)
+        mod1.write('def a_func():\n    pass\n')
+        mod2 = testutils.create_module(self.project, 'mod2', pkg)
+        mod2.write('from pkg.mod1 import a_func\n')
+        self._rename(mod2, 6, 'newpkg')
+        self.assertTrue(self.pycore.find_module('newpkg.mod1') is not None)
+        new_mod2 = self.pycore.find_module('newpkg.mod2')
+        self.assertEquals('from newpkg.mod1 import a_func\n', new_mod2.read())
+
+    def test_module_dependencies(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('class AClass(object):\n    pass\n')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod2.write('import mod1\na_var = mod1.AClass()\n')
+        self.pycore.resource_to_pyobject(mod2).get_attributes()['mod1']
+        mod1.write('def AClass():\n    return 0\n')
+
+        self._rename(mod2, len(mod2.read()) - 3, 'a_func')
+        self.assertEquals('def a_func():\n    return 0\n', mod1.read())
+        self.assertEquals('import mod1\na_var = mod1.a_func()\n', mod2.read())
+
+    def test_renaming_class_attributes(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('class AClass(object):\n    def __init__(self):\n'
+                   '        self.an_attr = 10\n')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod2.write('import mod1\na_var = mod1.AClass()\n'
+                   'another_var = a_var.an_attr')
+
+        self._rename(mod1, mod1.read().index('an_attr'), 'attr')
+        self.assertEquals('class AClass(object):\n    def __init__(self):\n'
+                          '        self.attr = 10\n', mod1.read())
+        self.assertEquals(
+            'import mod1\na_var = mod1.AClass()\nanother_var = a_var.attr',
+            mod2.read())
+
+    def test_renaming_class_attributes2(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('class AClass(object):\n    def __init__(self):\n'
+                   '        an_attr = 10\n        self.an_attr = 10\n')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod2.write('import mod1\na_var = mod1.AClass()\n'
+                   'another_var = a_var.an_attr')
+
+        self._rename(mod1, mod1.read().rindex('an_attr'), 'attr')
+        self.assertEquals(
+            'class AClass(object):\n    def __init__(self):\n'
+            '        an_attr = 10\n        self.attr = 10\n', mod1.read())
+        self.assertEquals(
+            'import mod1\na_var = mod1.AClass()\nanother_var = a_var.attr',
+            mod2.read())
+
+    def test_renaming_methods_in_subclasses(self):
+        mod = testutils.create_module(self.project, 'mod1')
+        mod.write('class A(object):\n    def a_method(self):\n        pass\n'
+                  'class B(A):\n    def a_method(self):\n        pass\n')
+
+        self._rename(mod, mod.read().rindex('a_method') + 1, 'new_method',
+                     in_hierarchy=True)
+        self.assertEquals(
+            'class A(object):\n    def new_method(self):\n        pass\n'
+            'class B(A):\n    def new_method(self):\n        pass\n', mod.read())
+
+    def test_renaming_methods_in_sibling_classes(self):
+        mod = testutils.create_module(self.project, 'mod1')
+        mod.write('class A(object):\n    def a_method(self):\n        pass\n'
+                  'class B(A):\n    def a_method(self):\n        pass\n'
+                  'class C(A):\n    def a_method(self):\n        pass\n')
+
+        self._rename(mod, mod.read().rindex('a_method') + 1, 'new_method',
+                     in_hierarchy=True)
+        self.assertEquals(
+            'class A(object):\n    def new_method(self):\n        pass\n'
+            'class B(A):\n    def new_method(self):\n        pass\n'
+            'class C(A):\n    def new_method(self):\n        pass\n', mod.read())
+
+    def test_not_renaming_methods_in_hierarchies(self):
+        mod = testutils.create_module(self.project, 'mod1')
+        mod.write('class A(object):\n    def a_method(self):\n        pass\n'
+                  'class B(A):\n    def a_method(self):\n        pass\n')
+
+        self._rename(mod, mod.read().rindex('a_method') + 1, 'new_method',
+                     in_hierarchy=False)
+        self.assertEquals(
+            'class A(object):\n    def a_method(self):\n        pass\n'
+            'class B(A):\n    def new_method(self):\n        pass\n', mod.read())
+
+    def test_undoing_refactorings(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('def a_func():\n    pass\na_func()\n')
+        self._rename(mod1, len(mod1.read()) - 5, 'new_func')
+        self.project.history.undo()
+        self.assertEquals('def a_func():\n    pass\na_func()\n', mod1.read())
+
+    def test_undoing_renaming_modules(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('def a_func():\n    pass\n')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod2.write('from mod1 import a_func\n')
+        self._rename(mod2, 6, 'newmod')
+        self.project.history.undo()
+        self.assertEquals('mod1.py', mod1.path)
+        self.assertEquals('from mod1 import a_func\n', mod2.read())
+
+    def test_rename_in_module_renaming_one_letter_names_for_expressions(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write('a = 10\nprint(1+a)\n')
+        pymod = self.pycore.get_module('mod1')
+        old_pyname = pymod['a']
+        finder = rope.refactor.occurrences.create_finder(
+            self.pycore, 'a', old_pyname)
+        refactored = rename.rename_in_module(
+            finder, 'new_var', pymodule=pymod, replace_primary=True)
+        self.assertEquals('new_var = 10\nprint(1+new_var)\n', refactored)
+
+    def test_renaming_for_loop_variable(self):
+        code = 'for var in range(10):\n    print(var)\n'
+        refactored = self._local_rename(code, code.find('var') + 1, 'new_var')
+        self.assertEquals('for new_var in range(10):\n    print(new_var)\n',
+                          refactored)
+
+    def test_renaming_parameters(self):
+        code = 'def a_func(param):\n    print(param)\na_func(param=hey)\n'
+        refactored = self._local_rename(code, code.find('param') + 1,
+                                        'new_param')
+        self.assertEquals('def a_func(new_param):\n    print(new_param)\n'
+                          'a_func(new_param=hey)\n', refactored)
+
+    def test_renaming_assigned_parameters(self):
+        code = 'def f(p):\n    p = p + 1\n    return p\nf(p=1)\n'
+        refactored = self._local_rename(code, code.find('p'), 'arg')
+        self.assertEquals('def f(arg):\n    arg = arg + 1\n'
+                          '    return arg\nf(arg=1)\n', refactored)
+
+    def test_renaming_parameters_not_renaming_others(self):
+        code = 'def a_func(param):\n    print(param)\nparam=10\na_func(param)\n'
+        refactored = self._local_rename(code, code.find('param') + 1, 'new_param')
+        self.assertEquals('def a_func(new_param):\n    print(new_param)\n'
+                          'param=10\na_func(param)\n', refactored)
+
+    def test_renaming_parameters_not_renaming_others2(self):
+        code = 'def a_func(param):\n    print(param)\nparam=10\na_func(param=param)'
+        refactored = self._local_rename(code, code.find('param') + 1, 'new_param')
+        self.assertEquals('def a_func(new_param):\n    print(new_param)\n'
+                          'param=10\na_func(new_param=param)', refactored)
+
+    def test_renaming_parameters_with_multiple_params(self):
+        code = 'def a_func(param1, param2):\n    print(param1)\n'\
+               'a_func(param1=1, param2=2)\n'
+        refactored = self._local_rename(code, code.find('param1') + 1, 'new_param')
+        self.assertEquals(
+            'def a_func(new_param, param2):\n    print(new_param)\n'
+            'a_func(new_param=1, param2=2)\n', refactored)
+
+    def test_renaming_parameters_with_multiple_params2(self):
+        code = 'def a_func(param1, param2):\n    print(param1)\n' \
+               'a_func(param1=1, param2=2)\n'
+        refactored = self._local_rename(code, code.rfind('param2') + 1,
+                                        'new_param')
+        self.assertEquals('def a_func(param1, new_param):\n    print(param1)\n'
+                          'a_func(param1=1, new_param=2)\n', refactored)
+
+    def test_renaming_parameters_on_calls(self):
+        code = 'def a_func(param):\n    print(param)\na_func(param = hey)\n'
+        refactored = self._local_rename(code, code.rfind('param') + 1,
+                                        'new_param')
+        self.assertEquals('def a_func(new_param):\n    print(new_param)\n'
+                          'a_func(new_param = hey)\n', refactored)
+
+    def test_renaming_parameters_spaces_before_call(self):
+        code = 'def a_func(param):\n    print(param)\na_func  (param=hey)\n'
+        refactored = self._local_rename(code, code.rfind('param') + 1,
+                                        'new_param')
+        self.assertEquals('def a_func(new_param):\n    print(new_param)\n'
+                          'a_func  (new_param=hey)\n', refactored)
+
+    def test_renaming_parameter_like_objects_after_keywords(self):
+        code = 'def a_func(param):\n    print(param)\ndict(param=hey)\n'
+        refactored = self._local_rename(code, code.find('param') + 1, 'new_param')
+        self.assertEquals('def a_func(new_param):\n    print(new_param)\n'
+                          'dict(param=hey)\n', refactored)
+
+    def test_renaming_variables_in_init_dot_pys(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        init_dot_py = pkg.get_child('__init__.py')
+        init_dot_py.write('a_var = 10\n')
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('import pkg\nprint(pkg.a_var)\n')
+        self._rename(mod, mod.read().index('a_var') + 1, 'new_var')
+        self.assertEquals('new_var = 10\n', init_dot_py.read())
+        self.assertEquals('import pkg\nprint(pkg.new_var)\n', mod.read())
+
+    def test_renaming_variables_in_init_dot_pys2(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        init_dot_py = pkg.get_child('__init__.py')
+        init_dot_py.write('a_var = 10\n')
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('import pkg\nprint(pkg.a_var)\n')
+        self._rename(init_dot_py,
+                     init_dot_py.read().index('a_var') + 1, 'new_var')
+        self.assertEquals('new_var = 10\n', init_dot_py.read())
+        self.assertEquals('import pkg\nprint(pkg.new_var)\n', mod.read())
+
+    def test_renaming_variables_in_init_dot_pys3(self):
+        pkg = testutils.create_package(self.project, 'pkg')
+        init_dot_py = pkg.get_child('__init__.py')
+        init_dot_py.write('a_var = 10\n')
+        mod = testutils.create_module(self.project, 'mod')
+        mod.write('import pkg\nprint(pkg.a_var)\n')
+        self._rename(mod, mod.read().index('a_var') + 1, 'new_var')
+        self.assertEquals('new_var = 10\n', init_dot_py.read())
+        self.assertEquals('import pkg\nprint(pkg.new_var)\n', mod.read())
+
+    def test_renaming_resources_using_rename_module_refactoring(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('a_var = 1')
+        mod2.write('import mod1\nmy_var = mod1.a_var\n')
+        renamer = rename.Rename(self.project, mod1)
+        renamer.get_changes('newmod').do()
+        self.assertEquals('import newmod\nmy_var = newmod.a_var\n', mod2.read())
+
+    def test_renaming_resources_using_rename_module_refactoring_for_packages(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1.write('import pkg\nmy_pkg = pkg')
+        renamer = rename.Rename(self.project, pkg)
+        renamer.get_changes('newpkg').do()
+        self.assertEquals('import newpkg\nmy_pkg = newpkg', mod1.read())
+
+    def test_renaming_resources_using_rename_module_refactoring_for_init_dot_py(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        pkg = testutils.create_package(self.project, 'pkg')
+        mod1.write('import pkg\nmy_pkg = pkg')
+        renamer = rename.Rename(self.project, pkg.get_child('__init__.py'))
+        renamer.get_changes('newpkg').do()
+        self.assertEquals('import newpkg\nmy_pkg = newpkg', mod1.read())
+
+    def test_renaming_global_variables(self):
+        code = 'a_var = 1\ndef a_func():\n    global a_var\n    var = a_var\n'
+        refactored = self._local_rename(code, code.index('a_var'), 'new_var')
+        self.assertEquals(
+            'new_var = 1\ndef a_func():\n    global new_var\n    var = new_var\n',
+            refactored)
+
+    def test_renaming_global_variables2(self):
+        code = 'a_var = 1\ndef a_func():\n    global a_var\n    var = a_var\n'
+        refactored = self._local_rename(code, code.rindex('a_var'), 'new_var')
+        self.assertEquals(
+            'new_var = 1\ndef a_func():\n    global new_var\n    var = new_var\n',
+            refactored)
+
+    def test_renaming_when_unsure(self):
+        code = 'class C(object):\n    def a_func(self):\n        pass\n' \
+               'def f(arg):\n    arg.a_func()\n'
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write(code)
+        self._rename(mod1, code.index('a_func'),
+                     'new_func', unsure=self._true)
+        self.assertEquals(
+            'class C(object):\n    def new_func(self):\n        pass\n' \
+            'def f(arg):\n    arg.new_func()\n',
+            mod1.read())
+
+    def _true(self, *args):
+        return True
+
+    def test_renaming_when_unsure_with_confirmation(self):
+        def confirm(occurrence):
+            return False
+        code = 'class C(object):\n    def a_func(self):\n        pass\n' \
+               'def f(arg):\n    arg.a_func()\n'
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write(code)
+        self._rename(mod1, code.index('a_func'), 'new_func', unsure=confirm)
+        self.assertEquals(
+            'class C(object):\n    def new_func(self):\n        pass\n' \
+            'def f(arg):\n    arg.a_func()\n', mod1.read())
+
+    def test_renaming_when_unsure_not_renaming_knowns(self):
+        code = 'class C1(object):\n    def a_func(self):\n        pass\n' \
+               'class C2(object):\n    def a_func(self):\n        pass\n' \
+               'c1 = C1()\nc1.a_func()\nc2 = C2()\nc2.a_func()\n'
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write(code)
+        self._rename(mod1, code.index('a_func'), 'new_func', unsure=self._true)
+        self.assertEquals(
+            'class C1(object):\n    def new_func(self):\n        pass\n' \
+            'class C2(object):\n    def a_func(self):\n        pass\n' \
+            'c1 = C1()\nc1.new_func()\nc2 = C2()\nc2.a_func()\n',
+            mod1.read())
+
+    def test_renaming_in_strings_and_comments(self):
+        code = 'a_var = 1\n# a_var\n'
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write(code)
+        self._rename(mod1, code.index('a_var'), 'new_var', docs=True)
+        self.assertEquals('new_var = 1\n# new_var\n', mod1.read())
+
+    def test_not_renaming_in_strings_and_comments_where_not_visible(self):
+        code = 'def f():\n    a_var = 1\n# a_var\n'
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write(code)
+        self._rename(mod1, code.index('a_var'), 'new_var', docs=True)
+        self.assertEquals('def f():\n    new_var = 1\n# a_var\n', mod1.read())
+
+    def test_not_renaming_all_text_occurrences_in_strings_and_comments(self):
+        code = 'a_var = 1\n# a_vard _a_var\n'
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write(code)
+        self._rename(mod1, code.index('a_var'), 'new_var', docs=True)
+        self.assertEquals('new_var = 1\n# a_vard _a_var\n', mod1.read())
+
+    def test_renaming_occurrences_in_overwritten_scopes(self):
+        refactored = self._local_rename(
+            'a_var = 20\ndef f():\n    print(a_var)\n'
+            'def f():\n    print(a_var)\n', 2, 'new_var')
+        self.assertEquals('new_var = 20\ndef f():\n    print(new_var)\n'
+                          'def f():\n    print(new_var)\n', refactored)
+
+    def test_renaming_occurrences_in_overwritten_scopes2(self):
+        code = 'def f():\n    a_var = 1\n    print(a_var)\n' \
+               'def f():\n    a_var = 1\n    print(a_var)\n'
+        refactored = self._local_rename(code, code.index('a_var') + 1, 'new_var')
+        self.assertEquals(code.replace('a_var', 'new_var', 2), refactored)
+
+    def test_dos_line_ending_and_renaming(self):
+        code = '\r\na = 1\r\n\r\nprint(2 + a + 2)\r\n'
+        offset = code.replace('\r\n', '\n').rindex('a')
+        refactored = self._local_rename(code, offset, 'b')
+        self.assertEquals('\nb = 1\n\nprint(2 + b + 2)\n',
+                          refactored.replace('\r\n', '\n'))
+
+    def test_multi_byte_strs_and_renaming(self):
+        s = u'{LATIN SMALL LETTER I WITH DIAERESIS}' * 4
+        code = u'# -*- coding: utf-8 -*-\n# ' + s + \
+                '\na = 1\nprint(2 + a + 2)\n'
+        refactored = self._local_rename(code, code.rindex('a'), 'b')
+        self.assertEquals(u'# -*- coding: utf-8 -*-\n# ' + s +
+                          '\nb = 1\nprint(2 + b + 2)\n', refactored)
+
+    def test_resources_parameter(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('def f():\n    pass\n')
+        mod2.write('import mod1\nmod1.f()\n')
+        self._rename(mod1, mod1.read().rindex('f'), 'g',
+                     resources=[mod1])
+        self.assertEquals('def g():\n    pass\n', mod1.read())
+        self.assertEquals('import mod1\nmod1.f()\n', mod2.read())
+
+    def test_resources_parameter_not_changing_defining_module(self):
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod1.write('def f():\n    pass\n')
+        mod2.write('import mod1\nmod1.f()\n')
+        self._rename(mod1, mod1.read().rindex('f'), 'g',
+                     resources=[mod2])
+        self.assertEquals('def f():\n    pass\n', mod1.read())
+        self.assertEquals('import mod1\nmod1.g()\n', mod2.read())
+
+    # XXX: with variables should not leak
+    @testutils.only_for('2.5')
+    def xxx_test_with_statement_variables_should_not_leak(self):
+        code = 'f = 1\nwith open("1.txt") as f:\n    print(f)\n'
+        if sys.version_info < (2, 6, 0):
+            code = 'from __future__ import with_statement\n' + code
+        mod1 = testutils.create_module(self.project, 'mod1')
+        mod1.write(code)
+        self._rename(mod1, code.rindex('f'), 'file')
+        expected = 'f = 1\nwith open("1.txt") as file:\n    print(file)\n'
+        self.assertEquals(expected, mod1.read())
+
+
+class ChangeOccurrencesTest(unittest.TestCase):
+
+    def setUp(self):
+        self.project = testutils.sample_project()
+        self.mod = testutils.create_module(self.project, 'mod')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(ChangeOccurrencesTest, self).tearDown()
+
+    def test_simple_case(self):
+        self.mod.write('a_var = 1\nprint(a_var)\n')
+        changer = rename.ChangeOccurrences(self.project, self.mod,
+                                           self.mod.read().index('a_var'))
+        changer.get_changes('new_var').do()
+        self.assertEquals('new_var = 1\nprint(new_var)\n', self.mod.read())
+
+    def test_only_performing_inside_scopes(self):
+        self.mod.write('a_var = 1\nnew_var = 2\ndef f():\n    print(a_var)\n')
+        changer = rename.ChangeOccurrences(self.project, self.mod,
+                                           self.mod.read().rindex('a_var'))
+        changer.get_changes('new_var').do()
+        self.assertEquals(
+            'a_var = 1\nnew_var = 2\ndef f():\n    print(new_var)\n',
+            self.mod.read())
+
+    def test_only_performing_on_calls(self):
+        self.mod.write('def f1():\n    pass\ndef f2():\n    pass\n'
+                       'g = f1\na = f1()\n')
+        changer = rename.ChangeOccurrences(self.project, self.mod,
+                                           self.mod.read().rindex('f1'))
+        changer.get_changes('f2', only_calls=True).do()
+        self.assertEquals(
+            'def f1():\n    pass\ndef f2():\n    pass\ng = f1\na = f2()\n',
+            self.mod.read())
+
+    def test_only_performing_on_reads(self):
+        self.mod.write('a = 1\nb = 2\nprint(a)\n')
+        changer = rename.ChangeOccurrences(self.project, self.mod,
+                                           self.mod.read().rindex('a'))
+        changer.get_changes('b', writes=False).do()
+        self.assertEquals('a = 1\nb = 2\nprint(b)\n', self.mod.read())
+
+
+class ImplicitInterfacesTest(unittest.TestCase):
+
+    def setUp(self):
+        super(ImplicitInterfacesTest, self).setUp()
+        self.project = testutils.sample_project(validate_objectdb=True)
+        self.pycore = self.project.pycore
+        self.mod1 = testutils.create_module(self.project, 'mod1')
+        self.mod2 = testutils.create_module(self.project, 'mod2')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(ImplicitInterfacesTest, self).tearDown()
+
+    def _rename(self, resource, offset, new_name, **kwds):
+        changes = Rename(self.project, resource, offset).\
+                  get_changes(new_name, **kwds)
+        self.project.do(changes)
+
+    def test_performing_rename_on_parameters(self):
+        self.mod1.write('def f(arg):\n    arg.run()\n')
+        self.mod2.write('import mod1\n\n\n'
+                        'class A(object):\n    def run(self):\n        pass\n'
+                        'class B(object):\n    def run(self):\n        pass\n'
+                        'mod1.f(A())\nmod1.f(B())\n')
+        self.pycore.analyze_module(self.mod2)
+        self._rename(self.mod1, self.mod1.read().index('run'), 'newrun')
+        self.assertEquals('def f(arg):\n    arg.newrun()\n', self.mod1.read())
+        self.assertEquals(
+            'import mod1\n\n\n'
+            'class A(object):\n    def newrun(self):\n        pass\n'
+            'class B(object):\n    def newrun(self):\n        pass\n'
+            'mod1.f(A())\nmod1.f(B())\n', self.mod2.read())
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(RenameRefactoringTest))
+    result.addTests(unittest.makeSuite(ChangeOccurrencesTest))
+    result.addTests(unittest.makeSuite(ImplicitInterfacesTest))
+    return result
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/refactor/restructuretest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,180 @@
+from rope.refactor import restructure
+from ropetest import testutils
+
+import unittest
+
+
+class RestructureTest(unittest.TestCase):
+
+    def setUp(self):
+        super(RestructureTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+        self.mod = testutils.create_module(self.project, 'mod')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(RestructureTest, self).tearDown()
+
+    def test_trivial_case(self):
+        refactoring = restructure.Restructure(self.project,
+                                              'a = 1', 'a = 0')
+        self.mod.write('b = 1\n')
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('b = 1\n', self.mod.read())
+
+    def test_replacing_simple_patterns(self):
+        refactoring = restructure.Restructure(self.project,
+                                              'a = 1', 'a = int(1)')
+        self.mod.write('a = 1\nb = 1\n')
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('a = int(1)\nb = 1\n', self.mod.read())
+
+    def test_replacing_patterns_with_normal_names(self):
+        refactoring = restructure.Restructure(
+            self.project, '${a} = 1', '${a} = int(1)', args={'a': 'exact'})
+        self.mod.write('a = 1\nb = 1\n')
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('a = int(1)\nb = 1\n', self.mod.read())
+
+    def test_replacing_patterns_with_any_names(self):
+        refactoring = restructure.Restructure(self.project,
+                                              '${a} = 1', '${a} = int(1)')
+        self.mod.write('a = 1\nb = 1\n')
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('a = int(1)\nb = int(1)\n', self.mod.read())
+
+    def test_replacing_patterns_with_any_names2(self):
+        refactoring = restructure.Restructure(
+            self.project, '${x} + ${x}', '${x} * 2')
+        self.mod.write('a = 1 + 1\n')
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('a = 1 * 2\n', self.mod.read())
+
+    def test_replacing_patterns_with_checks(self):
+        self.mod.write('def f(p=1):\n    return p\ng = f\ng()\n')
+        refactoring = restructure.Restructure(
+            self.project, '${f}()', '${f}(2)', args={'f': 'object=mod.f'})
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('def f(p=1):\n    return p\ng = f\ng(2)\n',
+                          self.mod.read())
+
+    def test_replacing_assignments_with_sets(self):
+        refactoring = restructure.Restructure(
+            self.project, '${a} = ${b}', '${a}.set(${b})')
+        self.mod.write('a = 1\nb = 1\n')
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('a.set(1)\nb.set(1)\n', self.mod.read())
+
+    def test_replacing_sets_with_assignments(self):
+        refactoring = restructure.Restructure(
+            self.project, '${a}.set(${b})', '${a} = ${b}')
+        self.mod.write('a.set(1)\nb.set(1)\n')
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('a = 1\nb = 1\n', self.mod.read())
+
+    def test_using_make_checks(self):
+        self.mod.write('def f(p=1):\n    return p\ng = f\ng()\n')
+        refactoring = restructure.Restructure(
+            self.project, '${f}()', '${f}(2)', args={'f': 'object=mod.f'})
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('def f(p=1):\n    return p\ng = f\ng(2)\n',
+                          self.mod.read())
+
+    def test_using_make_checking_builtin_types(self):
+        self.mod.write('a = 1 + 1\n')
+        refactoring = restructure.Restructure(
+            self.project, '${i} + ${i}', '${i} * 2',
+            args={'i': 'type=__builtin__.int'})
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('a = 1 * 2\n', self.mod.read())
+
+    def test_auto_indentation_when_no_indentation(self):
+        self.mod.write('a = 2\n')
+        refactoring = restructure.Restructure(
+            self.project, '${a} = 2', '${a} = 1\n${a} += 1')
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('a = 1\na += 1\n', self.mod.read())
+
+    def test_auto_indentation(self):
+        self.mod.write('def f():\n    a = 2\n')
+        refactoring = restructure.Restructure(
+            self.project, '${a} = 2', '${a} = 1\n${a} += 1')
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('def f():\n    a = 1\n    a += 1\n', self.mod.read())
+
+    def test_auto_indentation_and_not_indenting_blanks(self):
+        self.mod.write('def f():\n    a = 2\n')
+        refactoring = restructure.Restructure(
+            self.project, '${a} = 2', '${a} = 1\n\n${a} += 1')
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('def f():\n    a = 1\n\n    a += 1\n',
+                          self.mod.read())
+
+    def test_importing_names(self):
+        self.mod.write('a = 2\n')
+        refactoring = restructure.Restructure(
+            self.project, '${a} = 2', '${a} = myconsts.two',
+            imports=['import myconsts'])
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('import myconsts\na = myconsts.two\n',
+                          self.mod.read())
+
+    def test_not_importing_names_when_there_are_no_changes(self):
+        self.mod.write('a = True\n')
+        refactoring = restructure.Restructure(
+            self.project, '${a} = 2', '${a} = myconsts.two',
+            imports=['import myconsts'])
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('a = True\n', self.mod.read())
+
+    def test_handling_containing_matches(self):
+        self.mod.write('a = 1 / 2 / 3\n')
+        refactoring = restructure.Restructure(
+            self.project, '${a} / ${b}', '${a} // ${b}')
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('a = 1 // 2 // 3\n', self.mod.read())
+
+    def test_handling_overlapping_matches(self):
+        self.mod.write('a = 1\na = 1\na = 1\n')
+        refactoring = restructure.Restructure(
+            self.project, 'a = 1\na = 1\n', 'b = 1')
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('b = 1\na = 1\n', self.mod.read())
+
+    def test_preventing_stack_overflow_when_matching(self):
+        self.mod.write('1\n')
+        refactoring = restructure.Restructure(self.project, '${a}', '${a}')
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('1\n', self.mod.read())
+
+    def test_performing_a_restructuring_to_all_modules(self):
+        mod2 = testutils.create_module(self.project, 'mod2')
+        self.mod.write('a = 1\n')
+        mod2.write('b = 1\n')
+        refactoring = restructure.Restructure(self.project, '1', '2 / 1')
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('a = 2 / 1\n', self.mod.read())
+        self.assertEquals('b = 2 / 1\n', mod2.read())
+
+    def test_performing_a_restructuring_to_selected_modules(self):
+        mod2 = testutils.create_module(self.project, 'mod2')
+        self.mod.write('a = 1\n')
+        mod2.write('b = 1\n')
+        refactoring = restructure.Restructure(self.project, '1', '2 / 1')
+        self.project.do(refactoring.get_changes(resources=[mod2]))
+        self.assertEquals('a = 1\n', self.mod.read())
+        self.assertEquals('b = 2 / 1\n', mod2.read())
+
+    def test_unsure_argument_of_default_wildcard(self):
+        self.mod.write('def f(p):\n    return p * 2\nx = "" * 2\ni = 1 * 2\n')
+        refactoring = restructure.Restructure(
+            self.project, '${s} * 2', 'dup(${s})',
+            args={'s': {'type': '__builtins__.str','unsure': True}})
+        self.project.do(refactoring.get_changes())
+        self.assertEquals('def f(p):\n    return dup(p)\nx = dup("")\n'
+                          'i = 1 * 2\n', self.mod.read())
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/refactor/similarfindertest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,284 @@
+import unittest
+
+from rope.refactor import similarfinder
+from ropetest import testutils
+
+
+class SimilarFinderTest(unittest.TestCase):
+
+    def setUp(self):
+        super(SimilarFinderTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.mod = testutils.create_module(self.project, 'mod')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(SimilarFinderTest, self).tearDown()
+
+    def _create_finder(self, source, **kwds):
+        self.mod.write(source)
+        pymodule = self.project.pycore.resource_to_pyobject(self.mod)
+        return similarfinder.SimilarFinder(pymodule, **kwds)
+
+    def test_trivial_case(self):
+        finder = self._create_finder('')
+        self.assertEquals([], list(finder.get_match_regions('10')))
+
+    def test_constant_integer(self):
+        source = 'a = 10\n'
+        finder = self._create_finder(source)
+        result = [(source.index('10'), source.index('10') + 2)]
+        self.assertEquals(result, list(finder.get_match_regions('10')))
+
+    def test_simple_addition(self):
+        source = 'a = 1 + 2\n'
+        finder = self._create_finder(source)
+        result = [(source.index('1'), source.index('2') + 1)]
+        self.assertEquals(result, list(finder.get_match_regions('1 + 2')))
+
+    def test_simple_addition2(self):
+        source = 'a = 1 +2\n'
+        finder = self._create_finder(source)
+        result = [(source.index('1'), source.index('2') + 1)]
+        self.assertEquals(result, list(finder.get_match_regions('1 + 2')))
+
+    def test_simple_assign_statements(self):
+        source = 'a = 1 + 2\n'
+        finder = self._create_finder(source)
+        self.assertEquals([(0, len(source) - 1)],
+                          list(finder.get_match_regions('a = 1 + 2')))
+
+    def test_simple_multiline_statements(self):
+        source = 'a = 1\nb = 2\n'
+        finder = self._create_finder(source)
+        self.assertEquals([(0, len(source) - 1)],
+                          list(finder.get_match_regions('a = 1\nb = 2')))
+
+    def test_multiple_matches(self):
+        source = 'a = 1 + 1\n'
+        finder = self._create_finder(source)
+        result = list(finder.get_match_regions('1'))
+        self.assertEquals(2, len(result))
+        start1 = source.index('1')
+        self.assertEquals((start1, start1 + 1) , result[0])
+        start2 = source.rindex('1')
+        self.assertEquals((start2, start2 + 1) , result[1])
+
+    def test_multiple_matches2(self):
+        source = 'a = 1\nb = 2\n\na = 1\nb = 2\n'
+        finder = self._create_finder(source)
+        self.assertEquals(
+            2, len(list(finder.get_match_regions('a = 1\nb = 2'))))
+
+    def test_restricting_the_region_to_search(self):
+        source = '1\n\n1\n'
+        finder = self._create_finder(source)
+        result = list(finder.get_match_regions('1', start=2))
+        start = source.rfind('1')
+        self.assertEquals([(start, start + 1)], result)
+
+    def test_matching_basic_patterns(self):
+        source = 'b = a\n'
+        finder = self._create_finder(source)
+        result = list(finder.get_match_regions('${a}', args={'a': 'exact'}))
+        start = source.rfind('a')
+        self.assertEquals([(start, start + 1)], result)
+
+    def test_match_get_ast(self):
+        source = 'b = a\n'
+        finder = self._create_finder(source)
+        result = list(finder.get_matches('${a}', args={'a': 'exact'}))
+        self.assertEquals('a', result[0].get_ast('a').id)
+
+    def test_match_get_ast_for_statements(self):
+        source = 'b = a\n'
+        finder = self._create_finder(source)
+        result = list(finder.get_matches('b = ${a}'))
+        self.assertEquals('a', result[0].get_ast('a').id)
+
+    def test_matching_multiple_patterns(self):
+        source = 'c = a + b\n'
+        finder = self._create_finder(source)
+        result = list(finder.get_matches('${a} + ${b}'))
+        self.assertEquals('a', result[0].get_ast('a').id)
+        self.assertEquals('b', result[0].get_ast('b').id)
+
+    def test_matching_any_patterns(self):
+        source = 'b = a\n'
+        finder = self._create_finder(source)
+        result = list(finder.get_matches('b = ${x}'))
+        self.assertEquals('a', result[0].get_ast('x').id)
+
+    def test_matching_any_patterns_repeating(self):
+        source = 'b = 1 + 1\n'
+        finder = self._create_finder(source)
+        result = list(finder.get_matches('b = ${x} + ${x}'))
+        self.assertEquals(1, result[0].get_ast('x').n)
+
+    def test_matching_any_patterns_not_matching_different_nodes(self):
+        source = 'b = 1 + 2\n'
+        finder = self._create_finder(source)
+        result = list(finder.get_matches('b = ${x} + ${x}'))
+        self.assertEquals(0, len(result))
+
+    def test_matching_normal_names_and_assname(self):
+        source = 'a = 1\n'
+        finder = self._create_finder(source)
+        result = list(finder.get_matches('${a} = 1'))
+        self.assertEquals('a', result[0].get_ast('a').id)
+
+    def test_matching_normal_names_and_assname2(self):
+        source = 'a = 1\n'
+        finder = self._create_finder(source)
+        result = list(finder.get_matches('${a}', args={'a': 'exact'}))
+        self.assertEquals(1, len(result))
+
+    def test_matching_normal_names_and_attributes(self):
+        source = 'x.a = 1\n'
+        finder = self._create_finder(source)
+        result = list(finder.get_matches('${a} = 1', args={'a': 'exact'}))
+        self.assertEquals(0, len(result))
+
+    def test_functions_not_matching_when_only_first_parameters(self):
+        source = 'f(1, 2)\n'
+        finder = self._create_finder(source)
+        self.assertEquals(0, len(list(finder.get_matches('f(1)'))))
+
+    def test_matching_nested_try_finally(self):
+        source = 'if 1:\n    try:\n        pass\n    except:\n        pass\n'
+        pattern = 'try:\n    pass\nexcept:\n    pass\n'
+        finder = self._create_finder(source)
+        self.assertEquals(1, len(list(finder.get_matches(pattern))))
+
+    def test_matching_dicts_inside_functions(self):
+        source = 'def f(p):\n    d = {1: p.x}\n'
+        pattern = '{1: ${a}.x}'
+        finder = self._create_finder(source)
+        self.assertEquals(1, len(list(finder.get_matches(pattern))))
+
+
+class CheckingFinderTest(unittest.TestCase):
+
+    def setUp(self):
+        super(CheckingFinderTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+        self.mod1 = testutils.create_module(self.project, 'mod1')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(CheckingFinderTest, self).tearDown()
+
+    def test_trivial_case(self):
+        self.mod1.write('')
+        pymodule = self.pycore.resource_to_pyobject(self.mod1)
+        finder = similarfinder.SimilarFinder(pymodule)
+        self.assertEquals([], list(finder.get_matches('10', {})))
+
+    def test_simple_finding(self):
+        self.mod1.write('class A(object):\n    pass\na = A()\n')
+        pymodule = self.pycore.resource_to_pyobject(self.mod1)
+        finder = similarfinder.SimilarFinder(pymodule)
+        result = list(finder.get_matches('${anything} = ${A}()', {}))
+        self.assertEquals(1, len(result))
+
+    def test_not_matching_when_the_name_does_not_match(self):
+        self.mod1.write('class A(object):\n    pass\na = list()\n')
+        pymodule = self.pycore.resource_to_pyobject(self.mod1)
+        finder = similarfinder.SimilarFinder(pymodule)
+        result = list(finder.get_matches('${anything} = ${C}()',
+                                         {'C': 'name=mod1.A'}))
+        self.assertEquals(0, len(result))
+
+    def test_not_matching_unknowns_finding(self):
+        self.mod1.write('class A(object):\n    pass\na = unknown()\n')
+        pymodule = self.pycore.resource_to_pyobject(self.mod1)
+        finder = similarfinder.SimilarFinder(pymodule)
+        result = list(finder.get_matches('${anything} = ${C}()',
+                                         {'C': 'name=mod1.A'}))
+        self.assertEquals(0, len(result))
+
+    def test_finding_and_matching_pyobjects(self):
+        source = 'class A(object):\n    pass\nNewA = A\na = NewA()\n'
+        self.mod1.write(source)
+        pymodule = self.pycore.resource_to_pyobject(self.mod1)
+        finder = similarfinder.SimilarFinder(pymodule)
+        result = list(finder.get_matches('${anything} = ${A}()',
+                                         {'A': 'object=mod1.A'}))
+        self.assertEquals(1, len(result))
+        start = source.rindex('a =')
+        self.assertEquals((start, len(source) - 1), result[0].get_region())
+
+    def test_finding_and_matching_types(self):
+        source = 'class A(object):\n    def f(self):\n        pass\n' \
+                 'a = A()\nb = a.f()\n'
+        self.mod1.write(source)
+        pymodule = self.pycore.resource_to_pyobject(self.mod1)
+        finder = similarfinder.SimilarFinder(pymodule)
+        result = list(finder.get_matches('${anything} = ${inst}.f()',
+                                         {'inst': 'type=mod1.A'}))
+        self.assertEquals(1, len(result))
+        start = source.rindex('b')
+        self.assertEquals((start, len(source) - 1), result[0].get_region())
+
+    def test_checking_the_type_of_an_ass_name_node(self):
+        self.mod1.write('class A(object):\n    pass\nan_a = A()\n')
+        pymodule = self.pycore.resource_to_pyobject(self.mod1)
+        finder = similarfinder.SimilarFinder(pymodule)
+        result = list(finder.get_matches('${a} = ${assigned}',
+                                         {'a': 'type=mod1.A'}))
+        self.assertEquals(1, len(result))
+
+    def test_checking_instance_of_an_ass_name_node(self):
+        self.mod1.write('class A(object):\n    pass\n'
+                        'class B(A):\n    pass\nb = B()\n')
+        pymodule = self.pycore.resource_to_pyobject(self.mod1)
+        finder = similarfinder.SimilarFinder(pymodule)
+        result = list(finder.get_matches('${a} = ${assigned}',
+                                         {'a': 'instance=mod1.A'}))
+        self.assertEquals(1, len(result))
+
+    def test_checking_equality_of_imported_pynames(self):
+        mod2 = testutils.create_module(self.project, 'mod2')
+        mod2.write('class A(object):\n    pass\n')
+        self.mod1.write('from mod2 import A\nan_a = A()\n')
+        pymod2 = self.pycore.resource_to_pyobject(mod2)
+        pymod1 = self.pycore.resource_to_pyobject(self.mod1)
+        finder = similarfinder.SimilarFinder(pymod1)
+        result = list(finder.get_matches('${a_class}()',
+                                         {'a_class': 'name=mod2.A'}))
+        self.assertEquals(1, len(result))
+
+
+class TemplateTest(unittest.TestCase):
+
+    def test_simple_templates(self):
+        template = similarfinder.CodeTemplate('${a}\n')
+        self.assertEquals(set(['a']), set(template.get_names()))
+
+    def test_ignoring_matches_in_comments(self):
+        template = similarfinder.CodeTemplate('#${a}\n')
+        self.assertEquals([], template.get_names())
+
+    def test_ignoring_matches_in_strings(self):
+        template = similarfinder.CodeTemplate("'${a}'\n")
+        self.assertEquals([], template.get_names())
+
+    def test_simple_substitution(self):
+        template = similarfinder.CodeTemplate('${a}\n')
+        self.assertEquals('b\n', template.substitute({'a': 'b'}))
+
+    def test_substituting_multiple_names(self):
+        template = similarfinder.CodeTemplate('${a}, ${b}\n')
+        self.assertEquals('1, 2\n', template.substitute({'a': '1', 'b': '2'}))
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(SimilarFinderTest))
+    result.addTests(unittest.makeSuite(CheckingFinderTest))
+    result.addTests(unittest.makeSuite(TemplateTest))
+    return result
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/refactor/suitestest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,139 @@
+import unittest
+
+from rope.base import ast
+from rope.refactor import suites
+
+
+class SuiteTest(unittest.TestCase):
+
+    def setUp(self):
+        super(SuiteTest, self).setUp()
+
+    def tearDown(self):
+        super(SuiteTest, self).tearDown()
+
+    def test_trivial_case(self):
+        root = source_suite_tree('')
+        self.assertEquals(1, root.get_start())
+        self.assertEquals(0, len(root.get_children()))
+
+    def test_simple_ifs(self):
+        root = source_suite_tree('if True:\n    pass')
+        self.assertEquals(1, len(root.get_children()))
+
+    def test_simple_else(self):
+        root = source_suite_tree(
+            'if True:\n    pass\nelse:\n    pass\n')
+        self.assertEquals(2, len(root.get_children()))
+        self.assertEquals(1, root.get_children()[1].get_start())
+
+    def test_for(self):
+        root = source_suite_tree(
+            '\nfor i in range(10):\n    pass\nelse:\n    pass\n')
+        self.assertEquals(2, len(root.get_children()))
+        self.assertEquals(2, root.get_children()[1].get_start())
+
+    def test_while(self):
+        root = source_suite_tree(
+            'while True:\n    pass\n')
+        self.assertEquals(1, len(root.get_children()))
+        self.assertEquals(1, root.get_children()[0].get_start())
+
+    def test_with(self):
+        root = source_suite_tree(
+            'from __future__ import with_statement\nwith file(x):    pass\n')
+        self.assertEquals(1, len(root.get_children()))
+        self.assertEquals(2, root.get_children()[0].get_start())
+
+    def test_try_finally(self):
+        root = source_suite_tree(
+            'try:\n    pass\nfinally:\n    pass\n')
+        self.assertEquals(2, len(root.get_children()))
+        self.assertEquals(1, root.get_children()[0].get_start())
+
+    def test_try_except(self):
+        root = source_suite_tree(
+            'try:\n    pass\nexcept:\n    pass\nelse:\n    pass\n')
+        self.assertEquals(3, len(root.get_children()))
+        self.assertEquals(1, root.get_children()[2].get_start())
+
+    def test_try_except_finally(self):
+        root = source_suite_tree(
+            'try:\n    pass\nexcept:\n    pass\nfinally:\n    pass\n')
+        self.assertEquals(3, len(root.get_children()))
+        self.assertEquals(1, root.get_children()[2].get_start())
+
+    def test_local_start_and_end(self):
+        root = source_suite_tree('if True:\n    pass\nelse:\n    pass\n')
+        self.assertEquals(1, root.local_start())
+        self.assertEquals(4, root.local_end())
+        if_suite = root.get_children()[0]
+        self.assertEquals(2, if_suite.local_start())
+        self.assertEquals(2, if_suite.local_end())
+        else_suite = root.get_children()[1]
+        self.assertEquals(4, else_suite.local_start())
+        self.assertEquals(4, else_suite.local_end())
+
+    def test_find_suite(self):
+        root = source_suite_tree('\n')
+        self.assertEquals(root, root.find_suite(1))
+
+    def test_find_suite_for_ifs(self):
+        root = source_suite_tree('if True:\n    pass\n')
+        if_suite = root.get_children()[0]
+        self.assertEquals(if_suite, root.find_suite(2))
+
+    def test_find_suite_for_between_suites(self):
+        root = source_suite_tree(
+            'if True:\n    pass\nprint(1)\nif True:\n    pass\n')
+        if_suite1 = root.get_children()[0]
+        if_suite2 = root.get_children()[1]
+        self.assertEquals(if_suite1, root.find_suite(2))
+        self.assertEquals(if_suite2, root.find_suite(5))
+        self.assertEquals(root, root.find_suite(3))
+
+    def test_simple_find_visible(self):
+        root = source_suite_tree('a = 1\n')
+        self.assertEquals(1, suites.find_visible_for_suite(root, [1]))
+
+    def test_simple_find_visible_ifs(self):
+        root = source_suite_tree('\nif True:\n    a = 1\n    b = 2\n')
+        self.assertEquals(root.find_suite(3), root.find_suite(4))
+        self.assertEquals(3, suites.find_visible_for_suite(root, [3, 4]))
+
+    def test_simple_find_visible_for_else(self):
+        root = source_suite_tree('\nif True:\n    pass\nelse:    pass\n')
+        self.assertEquals(2, suites.find_visible_for_suite(root, [2, 4]))
+
+    def test_simple_find_visible_for_different_suites(self):
+        root = source_suite_tree('if True:\n    pass\na = 1\n'
+                                 'if False:\n    pass\n')
+        self.assertEquals(1, suites.find_visible_for_suite(root, [2, 3]))
+        self.assertEquals(5, suites.find_visible_for_suite(root, [5]))
+        self.assertEquals(1, suites.find_visible_for_suite(root, [2, 5]))
+
+    def test_not_always_selecting_scope_start(self):
+        root = source_suite_tree(
+            'if True:\n    a = 1\n    if True:\n        pass\n'
+            '    else:\n        pass\n')
+        self.assertEquals(3, suites.find_visible_for_suite(root, [4, 6]))
+        self.assertEquals(3, suites.find_visible_for_suite(root, [3, 5]))
+        self.assertEquals(3, suites.find_visible_for_suite(root, [4, 5]))
+
+    def test_ignoring_functions(self):
+        root = source_suite_tree(
+            'def f():\n    pass\na = 1\n')
+        self.assertEquals(3, suites.find_visible_for_suite(root, [2, 3]))
+
+    def test_ignoring_classes(self):
+        root = source_suite_tree(
+            'a = 1\nclass C():\n    pass\n')
+        self.assertEquals(1, suites.find_visible_for_suite(root, [1, 3]))
+
+
+def source_suite_tree(source):
+    return suites.ast_suite_tree(ast.parse(source))
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/refactor/usefunctiontest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,122 @@
+import unittest
+
+from rope.base import exceptions
+from ropetest import testutils
+from rope.refactor.usefunction import UseFunction
+
+
+class UseFunctionTest(unittest.TestCase):
+
+    def setUp(self):
+        super(UseFunctionTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.mod1 = testutils.create_module(self.project, 'mod1')
+        self.mod2 = testutils.create_module(self.project, 'mod2')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(UseFunctionTest, self).tearDown()
+
+    def test_simple_case(self):
+        code = 'def f():\n    pass\n'
+        self.mod1.write(code)
+        user = UseFunction(self.project, self.mod1, code.rindex('f'))
+        self.project.do(user.get_changes())
+        self.assertEquals(code, self.mod1.read())
+
+    def test_simple_function(self):
+        code = 'def f(p):\n    print(p)\nprint(1)\n'
+        self.mod1.write(code)
+        user = UseFunction(self.project, self.mod1, code.rindex('f'))
+        self.project.do(user.get_changes())
+        self.assertEquals('def f(p):\n    print(p)\nf(1)\n',
+                          self.mod1.read())
+
+    def test_simple_function2(self):
+        code = 'def f(p):\n    print(p + 1)\nprint(1 + 1)\n'
+        self.mod1.write(code)
+        user = UseFunction(self.project, self.mod1, code.rindex('f'))
+        self.project.do(user.get_changes())
+        self.assertEquals('def f(p):\n    print(p + 1)\nf(1)\n',
+                          self.mod1.read())
+
+    def test_functions_with_multiple_statements(self):
+        code = 'def f(p):\n    r = p + 1\n    print(r)\nr = 2 + 1\nprint(r)\n'
+        self.mod1.write(code)
+        user = UseFunction(self.project, self.mod1, code.rindex('f'))
+        self.project.do(user.get_changes())
+        self.assertEquals('def f(p):\n    r = p + 1\n    print(r)\nf(2)\n',
+                          self.mod1.read())
+
+    def test_returning(self):
+        code = 'def f(p):\n    return p + 1\nr = 2 + 1\nprint(r)\n'
+        self.mod1.write(code)
+        user = UseFunction(self.project, self.mod1, code.rindex('f'))
+        self.project.do(user.get_changes())
+        self.assertEquals(
+            'def f(p):\n    return p + 1\nr = f(2)\nprint(r)\n',
+            self.mod1.read())
+
+    def test_returning_a_single_expression(self):
+        code = 'def f(p):\n    return p + 1\nprint(2 + 1)\n'
+        self.mod1.write(code)
+        user = UseFunction(self.project, self.mod1, code.rindex('f'))
+        self.project.do(user.get_changes())
+        self.assertEquals(
+            'def f(p):\n    return p + 1\nprint(f(2))\n',
+            self.mod1.read())
+
+    def test_occurrences_in_other_modules(self):
+        code = 'def f(p):\n    return p + 1\n'
+        self.mod1.write(code)
+        user = UseFunction(self.project, self.mod1, code.rindex('f'))
+        self.mod2.write('print(2 + 1)\n')
+        self.project.do(user.get_changes())
+        self.assertEquals('import mod1\nprint(mod1.f(2))\n',
+                          self.mod2.read())
+
+    @testutils.assert_raises(exceptions.RefactoringError)
+    def test_when_performing_on_non_functions(self):
+        code = 'var = 1\n'
+        self.mod1.write(code)
+        user = UseFunction(self.project, self.mod1, code.rindex('var'))
+
+    def test_differing_in_the_inner_temp_names(self):
+        code = 'def f(p):\n    a = p + 1\n    print(a)\nb = 2 + 1\nprint(b)\n'
+        self.mod1.write(code)
+        user = UseFunction(self.project, self.mod1, code.rindex('f'))
+        self.project.do(user.get_changes())
+        self.assertEquals('def f(p):\n    a = p + 1\n    print(a)\nf(2)\n',
+                          self.mod1.read())
+
+    # TODO: probably new options should be added to restructure
+    def xxx_test_being_a_bit_more_intelligent_when_returning_assigneds(self):
+        code = 'def f(p):\n    a = p + 1\n    return a\n'\
+               'var = 2 + 1\nprint(var)\n'
+        self.mod1.write(code)
+        user = UseFunction(self.project, self.mod1, code.rindex('f'))
+        self.project.do(user.get_changes())
+        self.assertEquals('def f(p):\n    a = p + 1\n    return a\n'
+                          'var = f(p)\nprint(var)\n', self.mod1.read())
+
+    @testutils.assert_raises(exceptions.RefactoringError)
+    def test_exception_when_performing_a_function_with_yield(self):
+        code = 'def func():\n    yield 1\n'
+        self.mod1.write(code)
+        user = UseFunction(self.project, self.mod1, code.index('func'))
+
+    @testutils.assert_raises(exceptions.RefactoringError)
+    def test_exception_when_performing_a_function_two_returns(self):
+        code = 'def func():\n    return 1\n    return 2\n'
+        self.mod1.write(code)
+        user = UseFunction(self.project, self.mod1, code.index('func'))
+
+    @testutils.assert_raises(exceptions.RefactoringError)
+    def test_exception_when_returns_is_not_the_last_statement(self):
+        code = 'def func():\n    return 2\n    a = 1\n'
+        self.mod1.write(code)
+        user = UseFunction(self.project, self.mod1, code.index('func'))
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/runmodtest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,152 @@
+import os
+import unittest
+
+from rope.base import exceptions
+from ropetest import testutils
+
+
+class PythonFileRunnerTest(unittest.TestCase):
+
+    def setUp(self):
+        super(PythonFileRunnerTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.pycore = self.project.pycore
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(PythonFileRunnerTest, self).tearDown()
+
+    def make_sample_python_file(self, file_path, get_text_function_source=None):
+        self.project.root.create_file(file_path)
+        file = self.project.get_resource(file_path)
+        if not get_text_function_source:
+            get_text_function_source = "def get_text():\n    return 'run'\n\n"
+        file_content = get_text_function_source + \
+                       "output = open('output.txt', 'w')\n" \
+                       "output.write(get_text())\noutput.close()\n"
+        file.write(file_content)
+
+    def get_output_file_content(self, file_path):
+        try:
+            output_path = ''
+            last_slash = file_path.rfind('/')
+            if last_slash != -1:
+                output_path = file_path[0:last_slash + 1]
+            file = self.project.get_resource(output_path + 'output.txt')
+            return file.read()
+        except exceptions.ResourceNotFoundError:
+            return ''
+
+    def test_making_runner(self):
+        file_path = 'sample.py'
+        self.make_sample_python_file(file_path)
+        file_resource = self.project.get_resource(file_path)
+        runner = self.pycore.run_module(file_resource)
+        runner.wait_process()
+        self.assertEquals('run', self.get_output_file_content(file_path))
+
+    def test_passing_arguments(self):
+        file_path = 'sample.py'
+        function_source = 'import sys\ndef get_text():\n    return str(sys.argv[1:])\n'
+        self.make_sample_python_file(file_path, function_source)
+        file_resource = self.project.get_resource(file_path)
+        runner = self.pycore.run_module(file_resource, args=['hello', 'world'])
+        runner.wait_process()
+        self.assertTrue(self.get_output_file_content(file_path).endswith("['hello', 'world']"))
+
+    def test_passing_arguments_with_spaces(self):
+        file_path = 'sample.py'
+        function_source = 'import sys\ndef get_text():\n    return str(sys.argv[1:])\n'
+        self.make_sample_python_file(file_path, function_source)
+        file_resource = self.project.get_resource(file_path)
+        runner = self.pycore.run_module(file_resource, args=['hello world'])
+        runner.wait_process()
+        self.assertTrue(self.get_output_file_content(file_path).endswith("['hello world']"))
+
+    def test_killing_runner(self):
+        file_path = 'sample.py'
+        self.make_sample_python_file(file_path,
+                                     "def get_text():" +
+                                     "\n    import time\n    time.sleep(1)\n    return 'run'\n")
+        file_resource = self.project.get_resource(file_path)
+        runner = self.pycore.run_module(file_resource)
+        runner.kill_process()
+        self.assertEquals('', self.get_output_file_content(file_path))
+
+    def test_running_nested_files(self):
+        self.project.root.create_folder('src')
+        file_path = 'src/sample.py'
+        self.make_sample_python_file(file_path)
+        file_resource = self.project.get_resource(file_path)
+        runner = self.pycore.run_module(file_resource)
+        runner.wait_process()
+        self.assertEquals('run', self.get_output_file_content(file_path))
+
+    def test_setting_process_input(self):
+        file_path = 'sample.py'
+        self.make_sample_python_file(file_path,
+                                     "def get_text():" +
+                                     "\n    import sys\n    return sys.stdin.readline()\n")
+        temp_file_name = 'processtest.tmp'
+        try:
+            temp_file = open(temp_file_name, 'w')
+            temp_file.write('input text\n')
+            temp_file.close()
+            file_resource = self.project.get_resource(file_path)
+            stdin = open(temp_file_name)
+            runner = self.pycore.run_module(file_resource, stdin=stdin)
+            runner.wait_process()
+            stdin.close()
+            self.assertEquals('input text\n', self.get_output_file_content(file_path))
+        finally:
+            os.remove(temp_file_name)
+
+    def test_setting_process_output(self):
+        file_path = 'sample.py'
+        self.make_sample_python_file(file_path,
+                                     "def get_text():" +
+                                     "\n    print 'output text'\n    return 'run'\n")
+        temp_file_name = 'processtest.tmp'
+        try:
+            file_resource = self.project.get_resource(file_path)
+            stdout = open(temp_file_name, 'w')
+            runner = self.pycore.run_module(file_resource, stdout=stdout)
+            runner.wait_process()
+            stdout.close()
+            temp_file = open(temp_file_name, 'r')
+            self.assertEquals('output text\n', temp_file.read())
+            temp_file.close()
+        finally:
+            os.remove(temp_file_name)
+
+    def test_setting_pythonpath(self):
+        src = self.project.root.create_folder('src')
+        src.create_file('sample.py')
+        src.get_child('sample.py').write('def f():\n    pass\n')
+        self.project.root.create_folder('test')
+        file_path = 'test/test.py'
+        self.make_sample_python_file(file_path,
+                                     "def get_text():\n"
+                                     "    import sample\n    sample.f()\n    return'run'\n")
+        file_resource = self.project.get_resource(file_path)
+        runner = self.pycore.run_module(file_resource)
+        runner.wait_process()
+        self.assertEquals('run', self.get_output_file_content(file_path))
+
+    def test_making_runner_when_doi_is_disabled(self):
+        self.project.set('enable_doi', False)
+        file_path = 'sample.py'
+        self.make_sample_python_file(file_path)
+        file_resource = self.project.get_resource(file_path)
+        runner = self.pycore.run_module(file_resource)
+        runner.wait_process()
+        self.assertEquals('run', self.get_output_file_content(file_path))
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(PythonFileRunnerTest))
+    return result
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/simplifytest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,68 @@
+import unittest
+
+from rope.base import simplify
+
+
+class SimplifyTest(unittest.TestCase):
+
+    def setUp(self):
+        super(SimplifyTest, self).setUp()
+
+    def tearDown(self):
+        super(SimplifyTest, self).tearDown()
+
+    def test_trivial_case(self):
+        self.assertEquals('', simplify.real_code(''))
+
+    def test_empty_strs(self):
+        code = 's = ""\n'
+        self.assertEquals(code, simplify.real_code(code))
+
+    def test_blanking_strs(self):
+        code = 's = "..."\n'
+        self.assertEquals('s = "   "\n', simplify.real_code(code))
+
+    def test_changing_to_double_quotes(self):
+        code = 's = \'\'\n'
+        self.assertEquals('s = ""\n', simplify.real_code(code))
+
+    def test_changing_to_double_quotes2(self):
+        code = 's = """\n"""\n'
+        self.assertEquals('s = "     "\n', simplify.real_code(code))
+
+    def test_removing_comments(self):
+        code = '# c\n'
+        self.assertEquals('   \n', simplify.real_code(code))
+
+    def test_removing_comments_that_contain_strings(self):
+        code = '# "c"\n'
+        self.assertEquals('     \n', simplify.real_code(code))
+
+    def test_removing_strings_containing_comments(self):
+        code = '"#c"\n'
+        self.assertEquals('"  "\n', simplify.real_code(code))
+
+    def test_joining_implicit_continuations(self):
+        code = '(\n)\n'
+        self.assertEquals('( )\n', simplify.real_code(code))
+
+    def test_joining_explicit_continuations(self):
+        code = '1 + \\\n 2\n'
+        self.assertEquals('1 +    2\n', simplify.real_code(code))
+
+    def test_replacing_tabs(self):
+        code = '1\t+\t2\n'
+        self.assertEquals('1 + 2\n', simplify.real_code(code))
+
+    def test_replacing_semicolons(self):
+        code = 'a = 1;b = 2\n'
+        self.assertEquals('a = 1\nb = 2\n', simplify.real_code(code))
+
+
+def suite():
+    result = unittest.TestSuite()
+    result.addTests(unittest.makeSuite(SimplifyTest))
+    return result
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/ropetest/testutils.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,98 @@
+import os.path
+import shutil
+import sys
+
+import rope.base.project
+from rope.contrib import generate
+
+
+def sample_project(root=None, foldername=None, **kwds):
+    if root is None:
+        root = 'sample_project'
+        if foldername:
+            root = foldername
+        # HACK: Using ``/dev/shm/`` for faster tests
+        if os.name == 'posix' and os.path.isdir('/dev/shm'):
+            root = '/dev/shm/' + root
+    # Using these prefs for faster tests
+    prefs = {'save_objectdb': False, 'save_history': False,
+             'validate_objectdb': False, 'automatic_soa': False,
+             'ignored_resources': ['.ropeproject', '*.pyc'],
+             'import_dynload_stdmods': False}
+    prefs.update(kwds)
+    remove_recursively(root)
+    project = rope.base.project.Project(root, **prefs)
+    return project
+
+create_module = generate.create_module
+create_package = generate.create_package
+
+def remove_project(project):
+    project.close()
+    remove_recursively(project.address)
+
+
+def remove_recursively(path):
+    import time
+    # windows sometimes raises exceptions instead of removing files
+    if os.name == 'nt' or sys.platform == 'cygwin':
+          for i in range(12):
+            try:
+                _remove_recursively(path)
+            except OSError, e:
+                if e.errno not in (13, 16, 32):
+                    raise
+                time.sleep(0.3)
+            else:
+                break
+    else:
+        _remove_recursively(path)
+
+def _remove_recursively(path):
+    if not os.path.exists(path):
+        return
+    if os.path.isfile(path):
+        os.remove(path)
+    else:
+        shutil.rmtree(path)
+
+
+def run_only_for_25(func):
+    """Should be used as a decorator for a unittest.TestCase test method"""
+    if sys.version_info >= (2, 5, 0):
+        return func
+    else:
+        def do_nothing(self):
+            pass
+        return do_nothing
+
+
+def only_for(version):
+    """Should be used as a decorator for a unittest.TestCase test method"""
+    def decorator(func):
+        if sys.version >= version:
+            return func
+        else:
+            def do_nothing(self):
+                pass
+            return do_nothing
+    return decorator
+
+
+def run_only_for_unix(func):
+    """Should be used as a decorator for a unittest.TestCase test method"""
+    if os.name == 'posix':
+        return func
+    else:
+        def do_nothing(self):
+            pass
+        return do_nothing
+
+
+def assert_raises(exception_class):
+    """Should be used as a decorator for a unittest.TestCase test method"""
+    def _assert_raises(func):
+        def call_func(self, *args, **kws):
+            self.assertRaises(exception_class, func, self, *args, **kws)
+        return call_func
+    return _assert_raises
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/rope/setup.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,45 @@
+import glob
+import os
+import shutil
+
+extra_kwargs = {}
+try:
+    # we don't want to depend on setuptools
+    # please don't use any setuptools specific API
+    from setuptools import setup
+    extra_kwargs['test_suite'] = 'ropetest'
+except ImportError:
+    from distutils.core import setup
+
+import rope
+
+
+classifiers=[
+    'Development Status :: 4 - Beta',
+    'Operating System :: OS Independent',
+    'Environment :: X11 Applications',
+    'Environment :: Win32 (MS Windows)',
+    'Environment :: MacOS X',
+    'Intended Audience :: Developers',
+    'License :: OSI Approved :: GNU General Public License (GPL)',
+    'Natural Language :: English',
+    'Programming Language :: Python',
+    'Topic :: Software Development']
+
+def get_long_description():
+    lines = open('README.txt').read().splitlines(False)
+    end = lines.index('Getting Started')
+    return '\n' + '\n'.join(lines[:end]) + '\n'
+
+setup(name='rope',
+      version=rope.VERSION,
+      description='a python refactoring library...',
+      long_description=get_long_description(),
+      author='Ali Gholami Rudi',
+      author_email='aligrudi@users.sourceforge.net',
+      url='http://rope.sf.net/',
+      packages=['rope', 'rope.base', 'rope.base.oi', 'rope.refactor',
+                'rope.refactor.importutils', 'rope.contrib'],
+      license='GNU GPL',
+      classifiers=classifiers,
+      **extra_kwargs)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropemode/.hgignore	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,9 @@
+syntax:glob
+
+*.pyc
+*.*~
+*.*.orig
+*.egg-info
+doc/build
+build
+dist
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropemode/.hgtags	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,1 @@
+e75b75d70ac93804e9e4f90ddab8c294df8088b5 0.1-rc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropemode/ropemode/__init__.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,16 @@
+"""ropemode, a helper for using rope refactoring library in IDEs"""
+
+INFO = __doc__
+VERSION = '0.1-rc2'
+COPYRIGHT = """\
+Copyright (C) 2007-2008 Ali Gholami Rudi
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of GNU General Public License as published by the
+Free Software Foundation; either version 2 of the license, or (at your
+opinion) 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."""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropemode/ropemode/decorators.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,98 @@
+import traceback
+
+from rope.base import exceptions
+
+
+class Logger(object):
+
+    message = None
+    only_short = False
+
+    def __call__(self, message, short=None):
+        if short is None or not self.only_short:
+            self._show(message)
+        if short is not None:
+            self._show(short)
+
+    def _show(self, message):
+        if message is None:
+            print message
+        else:
+            self.message(message)
+
+logger = Logger()
+
+
+def lisphook(func):
+    def newfunc(*args, **kwds):
+        try:
+            func(*args, **kwds)
+        except Exception, e:
+            trace = str(traceback.format_exc())
+            short = 'Ignored an exception in ropemode hook: %s' % \
+                    _exception_message(e)
+            logger(trace, short)
+    newfunc.lisp = None
+    newfunc.__name__ = func.__name__
+    newfunc.__doc__ = func.__doc__
+    return newfunc
+
+
+def lispfunction(func):
+    func.lisp = None
+    return func
+
+
+input_exceptions = (exceptions.RefactoringError,
+                    exceptions.ModuleSyntaxError,
+                    exceptions.BadIdentifierError)
+
+def _exception_handler(func):
+    def newfunc(*args, **kwds):
+        try:
+            return func(*args, **kwds)
+        except exceptions.RopeError, e:
+            short = None
+            if isinstance(e, input_exceptions):
+                short = _exception_message(e)
+            logger(str(traceback.format_exc()), short)
+    newfunc.__name__ = func.__name__
+    newfunc.__doc__ = func.__doc__
+    return newfunc
+
+def _exception_message(e):
+    return '%s: %s' % (e.__class__.__name__, str(e))
+
+def rope_hook(hook):
+    def decorator(func):
+        func = lisphook(func)
+        func.name = func.__name__
+        func.kind = 'hook'
+        func.hook = hook
+        return func
+    return decorator
+
+
+def local_command(key=None, prefix=False, shortcut=None, name=None):
+    def decorator(func, name=name):
+        func = _exception_handler(func)
+        func.kind = 'local'
+        func.prefix = prefix
+        func.local_key = key
+        func.shortcut_key = shortcut
+        if name is None:
+            name = func.__name__
+        func.name = name
+        return func
+    return decorator
+
+
+def global_command(key=None, prefix=False):
+    def decorator(func):
+        func = _exception_handler(func)
+        func.kind = 'global'
+        func.prefix = prefix
+        func.global_key = key
+        func.name = func.__name__
+        return func
+    return decorator
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropemode/ropemode/dialog.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,97 @@
+class Data(object):
+
+    def __init__(self, prompt=None, default=None, values=None,
+                 kind=None, decode=None):
+        self.prompt = prompt
+        self.default = default
+        self.values = values
+        self.kind = kind
+        self._decode = decode
+
+    def decode(self, value):
+        if self._decode:
+            return self._decode(value)
+        return value
+
+
+class Boolean(Data):
+
+    def __init__(self, prompt=None, default=False):
+        Data.__init__(self, prompt, self._encode(default),
+                      [self._encode(True), self._encode(False)])
+
+    def _encode(self, value):
+        if value:
+            return 'yes'
+        return 'no'
+
+    def decode(self, value):
+        if value.lower() in ('yes', '1', 'true'):
+            return True
+        return False
+
+
+def show_dialog(askdata, actions, confs={}, optionals={}, initial_asking=True):
+    result = {}
+    if initial_asking:
+        for name, conf in confs.items():
+            result[name] = askdata(conf)
+    actions.append('batchset')
+    names = list(actions)
+    names.extend(optionals.keys())
+    names.extend(confs.keys())
+    base_question = Data('Choose what to do: ',
+                         default=actions[0], values=names)
+    batchset_question = Data('Batch sets: ')
+    while True:
+        response = askdata(base_question)
+        if response == '':
+            response = base_question.default
+        elif response == 'batchset':
+            sets = askdata(batchset_question)
+            for key, value in _parse_batchset(sets).items():
+                if key.endswith(':'):
+                    key = key[:-1]
+                if key in names:
+                    conf = confs.get(key, optionals.get(key))
+                    result[key] = value
+        elif response in actions:
+            break
+        else:
+            if response in confs:
+                conf = confs[response]
+            else:
+                conf = optionals[response]
+            oldvalue = result.get(response, None)
+            result[response] = askdata(conf, starting=oldvalue)
+    decoded = {}
+    all_confs = dict(confs)
+    all_confs.update(optionals)
+    for key in all_confs:
+        conf = all_confs.get(key)
+        if key in result:
+            decoded[key] = conf.decode(result[key])
+        else:
+            decoded[key] = conf.decode(conf.default)
+    return response, decoded
+
+
+def _parse_batchset(sets):
+    result = []
+    multiline = False
+    for line in sets.splitlines(True):
+        if line[0].isspace():
+            if multiline:
+                result[-1][1] += line[1:]
+        else:
+            if not line.strip():
+                continue
+            multiline= False
+            tokens = line.split(None, 1)
+            value = ''
+            if len(tokens) > 1:
+                result.append([tokens[0], tokens[1].rstrip('\r\n')])
+            else:
+                multiline = True
+                result.append([tokens[0], ''])
+    return dict(result)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropemode/ropemode/environment.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,101 @@
+class Environment(object):
+
+    def ask(self, prompt, default=None, starting=None):
+        pass
+
+    def ask_values(self, prompt, values, default=None, starting=None):
+        pass
+
+    def ask_directory(self, prompt, default=None, starting=None):
+        pass
+
+    def ask_completion(self, prompt, values, starting=None):
+        pass
+
+    def message(self, message):
+        pass
+
+    def yes_or_no(self, prompt):
+        pass
+
+    def y_or_n(self, prompt):
+        pass
+
+    def get(self, name, default=None):
+        pass
+
+    def get_offset(self):
+        pass
+
+    def get_text(self):
+        pass
+
+    def get_region(self):
+        pass
+
+    def filename(self):
+        pass
+
+    def is_modified(self):
+        pass
+
+    def goto_line(self, lineno):
+        pass
+
+    def insert_line(self, line, lineno):
+        pass
+
+    def insert(self, text):
+        pass
+
+    def delete(self, start, end):
+        pass
+
+    def filenames(self):
+        pass
+
+    def save_files(self, filenames):
+        pass
+
+    def reload_files(self, filenames, moves={}):
+        pass
+
+    def find_file(self, filename, readonly=False, other=False):
+        pass
+
+    def create_progress(self, name):
+        pass
+
+    def current_word(self):
+        pass
+
+    def push_mark(self):
+        pass
+
+    def prefix_value(self, prefix):
+        pass
+
+    def show_occurrences(self, locations):
+        pass
+
+    def show_doc(self, docs, altview=False):
+        pass
+
+    def preview_changes(self, diffs):
+        pass
+
+    def local_command(self, name, callback, key=None, prefix=False):
+        pass
+
+    def global_command(self, name, callback, key=None, prefix=False):
+        pass
+
+    def add_hook(self, name, callback, hook):
+        pass
+
+    def _completion_text(self, proposal):
+        return proposal.name
+
+    def _completion_data(self, proposal):
+        return self._completion_text(proposal)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropemode/ropemode/filter.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,39 @@
+from rope.base import exceptions
+
+
+def resources(project, rules):
+    """Find python files in the `project` matching `rules`
+
+    `rules` is a multi-line `str`; each line starts with either a '+'
+    or '-'.  Each '+' means include the file (or its children if it's
+    a folder) that comes after it.  '-' has the same meaning for
+    exclusion.
+
+    """
+    all = set(project.pycore.get_python_files())
+    files = None
+    for line in rules.splitlines():
+        if not line.strip():
+            continue
+        first, path = (line[0], line[1:])
+        if first not in '+-':
+            continue
+        try:
+            resource = project.get_resource(path.strip())
+        except exceptions.ResourceNotFoundError:
+            continue
+        if resource.is_folder():
+            matches = set(filter(lambda item: resource.contains(item), all))
+        else:
+            matches = set([resource])
+        if first == '+':
+            if files is None:
+                files = set()
+            files.update(matches)
+        if first == '-':
+            if files is None:
+                files = set(all)
+            files -= matches
+    if files is None:
+        return all
+    return files
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropemode/ropemode/interface.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,677 @@
+import os
+
+import rope.base.change
+from rope.base import libutils, utils, exceptions
+from rope.contrib import codeassist, generate, autoimport, findit
+
+from ropemode import refactor, decorators, dialog
+
+
+class RopeMode(object):
+
+    def __init__(self, env):
+        self.project = None
+        self.old_content = None
+        self.env = env
+
+        self._prepare_refactorings()
+        self.autoimport = None
+        self._init_mode()
+
+    def init(self):
+        """Initialize rope mode"""
+
+    def _init_mode(self):
+        for attrname in dir(self):
+            attr = getattr(self, attrname)
+            if not callable(attr):
+                continue
+            kind = getattr(attr, 'kind', None)
+            if kind == 'local':
+                key = getattr(attr, 'local_key', None)
+                prefix = getattr(attr, 'prefix', None)
+                self.env.local_command(attrname, attr, key, prefix)
+            if kind == 'global':
+                key = getattr(attr, 'global_key', None)
+                prefix = getattr(attr, 'prefix', None)
+                self.env.global_command(attrname, attr, key, prefix)
+            if kind == 'hook':
+                hook = getattr(attr, 'hook', None)
+                self.env.add_hook(attrname, attr, hook)
+
+    def _prepare_refactorings(self):
+        for name in dir(refactor):
+            if not name.startswith('_') and name != 'Refactoring':
+                attr = getattr(refactor, name)
+                if isinstance(attr, type) and \
+                   issubclass(attr, refactor.Refactoring):
+                    refname = self._refactoring_name(attr)
+                    @decorators.local_command(attr.key, 'P', None, refname)
+                    def do_refactor(prefix, self=self, refactoring=attr):
+                        initial_asking = prefix is None
+                        refactoring(self, self.env).show(initial_asking=initial_asking)
+                    setattr(self, refname, do_refactor)
+
+    def _refactoring_name(self, refactoring):
+        return refactor.refactoring_name(refactoring)
+
+    @decorators.rope_hook('before_save')
+    def before_save_actions(self):
+        if self.project is not None:
+            if not self._is_python_file(self.env.filename()):
+                return
+            resource = self._get_resource()
+            if resource.exists():
+                self.old_content = resource.read()
+            else:
+                self.old_content = ''
+
+    @decorators.rope_hook('after_save')
+    def after_save_actions(self):
+        if self.project is not None and self.old_content is not None:
+            libutils.report_change(self.project, self.env.filename(),
+                                   self.old_content)
+            self.old_content = None
+
+    @decorators.rope_hook('exit')
+    def exiting_actions(self):
+        if self.project is not None:
+            self.close_project()
+
+    @decorators.global_command('o')
+    def open_project(self, root=None):
+        if not root:
+            root = self.env.ask_directory('Rope project root folder: ')
+        if self.project is not None:
+            self.close_project()
+        address = rope.base.project._realpath(os.path.join(root,
+                                                           '.ropeproject'))
+        if not os.path.exists(address):
+            if not self.env.y_or_n('Project not exists in %s, ' \
+                                   'create one?' % root):
+                self.env.message("Project creation aborted")
+                return
+        progress = self.env.create_progress('Opening [%s] project' % root)
+        self.project = rope.base.project.Project(root)
+        if self.env.get('enable_autoimport'):
+            underlined = self.env.get('autoimport_underlineds')
+            self.autoimport = autoimport.AutoImport(self.project,
+                                                    underlined=underlined)
+        progress.done()
+
+    @decorators.global_command('k')
+    def close_project(self):
+        if self.project is not None:
+            progress = self.env.create_progress('Closing [%s] project' %
+                                                self.project.address)
+            self.project.close()
+            self.project = None
+            progress.done()
+
+    @decorators.global_command()
+    def write_project(self):
+        if self.project is not None:
+            progress = self.env.create_progress(
+                'Writing [%s] project data to disk' % self.project.address)
+            self.project.sync()
+            progress.done()
+
+    @decorators.global_command('u')
+    def undo(self):
+        self._check_project()
+        change = self.project.history.tobe_undone
+        if change is None:
+            self.env.message('Nothing to undo!')
+            return
+        if self.env.y_or_n('Undo [%s]? ' % str(change)):
+            def undo(handle):
+                for changes in self.project.history.undo(task_handle=handle):
+                    self._reload_buffers(changes, undo=True)
+            refactor.runtask(self.env, undo, 'Undo refactoring',
+                             interrupts=False)
+
+    @decorators.global_command('r')
+    def redo(self):
+        self._check_project()
+        change = self.project.history.tobe_redone
+        if change is None:
+            self.env.message('Nothing to redo!')
+            return
+        if self.env.y_or_n('Redo [%s]? ' % str(change)):
+            def redo(handle):
+                for changes in self.project.history.redo(task_handle=handle):
+                    self._reload_buffers(changes)
+            refactor.runtask(self.env, redo, 'Redo refactoring',
+                             interrupts=False)
+
+    @decorators.local_command('a g', shortcut='C-c g')
+    def goto_definition(self):
+        definition = self._base_definition_location()
+        if definition:
+            self.env.push_mark()
+            self._goto_location(definition[0], definition[1])
+        else:
+            self.env.message('Cannot find the definition!')
+
+    @decorators.local_command()
+    def definition_location(self):
+        definition = self._base_definition_location()
+        if definition:
+            return str(definition[0].real_path), definition[1]
+        return None
+
+    def _base_definition_location(self):
+        self._check_project()
+        resource, offset = self._get_location()
+        maxfixes = self.env.get('codeassist_maxfixes')
+        try:
+            definition = codeassist.get_definition_location(
+                self.project, self._get_text(), offset, resource, maxfixes)
+        except exceptions.BadIdentifierError:
+            return None
+        if tuple(definition) != (None, None):
+            return definition
+        return None
+
+    @decorators.local_command('a d', 'P', 'C-c d')
+    def show_doc(self, prefix):
+        self._check_project()
+        self._base_show_doc(prefix, codeassist.get_doc)
+
+    @decorators.local_command('a c', 'P')
+    def show_calltip(self, prefix):
+        self._check_project()
+        def _get_doc(project, text, offset, *args, **kwds):
+            try:
+                offset = text.rindex('(', 0, offset) - 1
+            except ValueError:
+                return None
+            return codeassist.get_calltip(project, text, offset, *args, **kwds)
+        self._base_show_doc(prefix, _get_doc)
+
+    def _base_show_doc(self, prefix, get_doc):
+        docs = self._base_get_doc(get_doc)
+        if docs:
+            self.env.show_doc(docs, prefix)
+        else:
+            self.env.message('No docs available!')
+
+    @decorators.local_command()
+    def get_doc(self):
+        self._check_project()
+        return self._base_get_doc(codeassist.get_doc)
+
+    def _base_get_doc(self, get_doc):
+        maxfixes = self.env.get('codeassist_maxfixes')
+        text = self._get_text()
+        offset = self.env.get_offset()
+        try:
+            return get_doc(self.project, text, offset,
+                           self.resource, maxfixes)
+        except exceptions.BadIdentifierError:
+            return None
+
+    def _get_text(self):
+        resource = self.resource
+        if not self.env.is_modified() and resource is not None:
+            return resource.read()
+        return self.env.get_text()
+
+    def _base_findit(self, do_find, optionals, get_kwds):
+        self._check_project()
+        self._save_buffers()
+        resource, offset = self._get_location()
+
+        action, values = dialog.show_dialog(
+            self._askdata, ['search', 'cancel'], optionals=optionals)
+        if action == 'search':
+            kwds = get_kwds(values)
+            def calculate(handle):
+                resources = refactor._resources(self.project,
+                                                values.get('resources'))
+                return do_find(self.project, resource, offset,
+                               resources=resources, task_handle=handle, **kwds)
+            result = refactor.runtask(self.env, calculate, 'Find Occurrences')
+            locations = [Location(location) for location in result]
+            self.env.show_occurrences(locations)
+
+    @decorators.local_command('a f', shortcut='C-c f')
+    def find_occurrences(self):
+        optionals = {
+            'unsure': dialog.Data('Find uncertain occurrences: ',
+                                  default='no', values=['yes', 'no']),
+            'resources': dialog.Data('Files to search: '),
+            'in_hierarchy': dialog.Data(
+                    'Rename methods in class hierarchy: ',
+                    default='no', values=['yes', 'no'])}
+        def get_kwds(values):
+            return {'unsure': values.get('unsure') == 'yes',
+                    'in_hierarchy': values.get('in_hierarchy') == 'yes'}
+        self._base_findit(findit.find_occurrences, optionals, get_kwds)
+
+    @decorators.local_command('a i')
+    def find_implementations(self):
+        optionals = {'resources': dialog.Data('Files to search: ')}
+        def get_kwds(values):
+            return {}
+        self._base_findit(findit.find_implementations, optionals, get_kwds)
+
+    @decorators.local_command('a /', 'P', 'M-/')
+    def code_assist(self, prefix):
+        _CodeAssist(self, self.env).code_assist(prefix)
+
+    @decorators.local_command('a ?', 'P', 'M-?')
+    def lucky_assist(self, prefix):
+        _CodeAssist(self, self.env).lucky_assist(prefix)
+
+    @decorators.local_command()
+    def auto_import(self):
+        _CodeAssist(self, self.env).auto_import()
+
+    @decorators.local_command()
+    def completions(self):
+        return _CodeAssist(self, self.env).completions()
+
+    @decorators.local_command()
+    def extended_completions(self):
+        return _CodeAssist(self, self.env).extended_completions()
+
+    def _check_autoimport(self):
+        self._check_project()
+        if self.autoimport is None:
+            self.env.message('autoimport is disabled; '
+                             'see `enable_autoimport\' variable')
+            return False
+        return True
+
+    @decorators.global_command()
+    def generate_autoimport_cache(self):
+        if not self._check_autoimport():
+            return
+        modules = self.env.get('autoimport_modules')
+        modnames = []
+        if modules:
+            for i in range(len(modules)):
+                modname = modules[i]
+                if not isinstance(modname, basestring):
+                    modname = modname.value()
+                modnames.append(modname)
+        else:
+            modules = []
+        def generate(handle):
+            self.autoimport.generate_cache(task_handle=handle)
+            self.autoimport.generate_modules_cache(modules, task_handle=handle)
+        refactor.runtask(self.env, generate, 'Generate autoimport cache')
+
+    @decorators.global_command('f', 'P')
+    def find_file(self, prefix):
+        file = self._base_find_file(prefix)
+        if file is not None:
+            self.env.find_file(file.real_path)
+
+    @decorators.global_command('4 f', 'P')
+    def find_file_other_window(self, prefix):
+        file = self._base_find_file(prefix)
+        if file is not None:
+            self.env.find_file(file.real_path, other=True)
+
+    def _base_find_file(self, prefix):
+        self._check_project()
+        if prefix:
+            files = self.project.pycore.get_python_files()
+        else:
+            files = self.project.get_files()
+        return self._ask_file(files)
+
+    def _ask_file(self, files):
+        names = []
+        for file in files:
+            names.append('<'.join(reversed(file.path.split('/'))))
+        result = self.env.ask_values('Rope Find File: ', names)
+        if result is not None:
+            path = '/'.join(reversed(result.split('<')))
+            file = self.project.get_file(path)
+            return file
+        self.env.message('No file selected')
+
+    @decorators.local_command('a j')
+    def jump_to_global(self):
+        if not self._check_autoimport():
+            return
+        all_names = list(self.autoimport.get_all_names())
+        name = self.env.ask_values('Global name: ', all_names)
+        result = dict(self.autoimport.get_name_locations(name))
+        if len(result) == 1:
+            resource = list(result.keys())[0]
+        else:
+            resource = self._ask_file(result.keys())
+        if resource:
+            self._goto_location(resource, result[resource])
+
+    @decorators.global_command('c')
+    def project_config(self):
+        self._check_project()
+        if self.project.ropefolder is not None:
+            config = self.project.ropefolder.get_child('config.py')
+            self.env.find_file(config.real_path)
+        else:
+            self.env.message('No rope project folder found')
+
+    @decorators.global_command('n m')
+    def create_module(self):
+        def callback(sourcefolder, name):
+            return generate.create_module(self.project, name, sourcefolder)
+        self._create('module', callback)
+
+    @decorators.global_command('n p')
+    def create_package(self):
+        def callback(sourcefolder, name):
+            folder = generate.create_package(self.project, name, sourcefolder)
+            return folder.get_child('__init__.py')
+        self._create('package', callback)
+
+    @decorators.global_command('n f')
+    def create_file(self):
+        def callback(parent, name):
+            return parent.create_file(name)
+        self._create('file', callback, 'parent')
+
+    @decorators.global_command('n d')
+    def create_directory(self):
+        def callback(parent, name):
+            parent.create_folder(name)
+        self._create('directory', callback, 'parent')
+
+    @decorators.local_command()
+    def analyze_module(self):
+        """Perform static object analysis on this module"""
+        self._check_project()
+        self.project.pycore.analyze_module(self.resource)
+
+    @decorators.global_command()
+    def analyze_modules(self):
+        """Perform static object analysis on all project modules"""
+        self._check_project()
+        def _analyze_modules(handle):
+            libutils.analyze_modules(self.project, task_handle=handle)
+        refactor.runtask(self.env, _analyze_modules, 'Analyze project modules')
+
+    @decorators.local_command()
+    def run_module(self):
+        """Run and perform dynamic object analysis on this module"""
+        self._check_project()
+        process = self.project.pycore.run_module(self.resource)
+        try:
+            process.wait_process()
+        finally:
+            process.kill_process()
+
+    def _create(self, name, callback, parentname='source'):
+        self._check_project()
+        confs = {'name': dialog.Data(name.title() + ' name: ')}
+        parentname = parentname + 'folder'
+        optionals = {parentname: dialog.Data(
+                parentname.title() + ' Folder: ',
+                default=self.project.address, kind='directory')}
+        action, values = dialog.show_dialog(
+            self._askdata, ['perform', 'cancel'], confs, optionals)
+        if action == 'perform':
+            parent = libutils.path_to_resource(
+                self.project, values.get(parentname, self.project.address))
+            resource = callback(parent, values['name'])
+            if resource:
+                self.env.find_file(resource.real_path)
+
+    def _goto_location(self, resource, lineno):
+        if resource:
+            self.env.find_file(str(resource.real_path),
+                               other=self.env.get('goto_def_newwin'))
+        if lineno:
+            self.env.goto_line(lineno)
+
+    def _get_location(self):
+        offset = self.env.get_offset()
+        return self.resource, offset
+
+    def _get_resource(self, filename=None):
+        if filename is None:
+            filename = self.env.filename()
+        if filename is None or self.project is None:
+            return
+        resource = libutils.path_to_resource(self.project, filename, 'file')
+        return resource
+
+    @property
+    def resource(self):
+        """the current resource
+
+        Returns `None` when file does not exist.
+        """
+        resource = self._get_resource()
+        if resource and resource.exists():
+            return resource
+
+    def _check_project(self):
+        if self.project is None:
+            if self.env.get('guess_project'):
+                self.open_project(self._guess_project())
+            else:
+                self.open_project()
+        else:
+            self.project.validate(self.project.root)
+
+    def _guess_project(self):
+        cwd = self.env.filename()
+        if cwd is not None:
+            while True:
+                ropefolder = os.path.join(cwd, '.ropeproject')
+                if os.path.exists(ropefolder) and os.path.isdir(ropefolder):
+                    return cwd
+                newcwd = os.path.dirname(cwd)
+                if newcwd == cwd:
+                    break
+                cwd = newcwd
+
+    def _reload_buffers(self, changes, undo=False):
+        self._reload_buffers_for_changes(
+            changes.get_changed_resources(),
+            self._get_moved_resources(changes, undo))
+
+    def _reload_buffers_for_changes(self, changed, moved={}):
+        filenames = [resource.real_path for resource in changed]
+        moved = dict([(resource.real_path, moved[resource].real_path)
+                      for resource in moved])
+        self.env.reload_files(filenames, moved)
+
+    def _get_moved_resources(self, changes, undo=False):
+        result = {}
+        if isinstance(changes, rope.base.change.ChangeSet):
+            for change in changes.changes:
+                result.update(self._get_moved_resources(change))
+        if isinstance(changes, rope.base.change.MoveResource):
+            result[changes.resource] = changes.new_resource
+        if undo:
+            return dict([(value, key) for key, value in result.items()])
+        return result
+
+    def _save_buffers(self, only_current=False):
+        if only_current:
+            filenames = [self.env.filename()]
+        else:
+            filenames = self.env.filenames()
+        pythons = []
+        for filename in filenames:
+            if self._is_python_file(filename):
+                pythons.append(filename)
+        self.env.save_files(pythons)
+
+    def _is_python_file(self, path):
+        resource = self._get_resource(path)
+        return (resource is not None and
+                resource.project == self.project and
+                self.project.pycore.is_python_file(resource))
+
+    def _askdata(self, data, starting=None):
+        ask_func = self.env.ask
+        ask_args = {'prompt': data.prompt, 'starting': starting,
+                    'default': data.default}
+        if data.values:
+            ask_func = self.env.ask_values
+            ask_args['values'] = data.values
+        elif data.kind == 'directory':
+            ask_func = self.env.ask_directory
+        return ask_func(**ask_args)
+
+
+class Location(object):
+    def __init__(self, location):
+        self.location = location
+        self.filename = location.resource.real_path
+        self.offset = location.offset
+        self.note = ''
+        if location.unsure:
+            self.note = '?'
+
+    @property
+    def lineno(self):
+        if hasattr(self.location, 'lineno'):
+            return self.location.lineno
+        return self.location.resource.read().count('\n', 0, self.offset) + 1
+
+
+class _CodeAssist(object):
+
+    def __init__(self, interface, env):
+        self.interface = interface
+        self.env = env
+
+    def code_assist(self, prefix):
+        proposals = self._calculate_proposals()
+        if prefix is not None:
+            arg = self.env.prefix_value(prefix)
+            if arg == 0:
+                arg = len(proposals)
+            common_start = self._calculate_prefix(proposals[:arg])
+            self.env.insert(common_start[self.offset - self.starting_offset:])
+            self._starting = common_start
+            self._offset = self.starting_offset + len(common_start)
+        prompt = 'Completion for %s: ' % self.expression
+        proposals = map(self.env._completion_data, proposals)
+        result = self.env.ask_completion(prompt, proposals, self.starting)
+        if result is not None:
+            self._apply_assist(result)
+
+    def lucky_assist(self, prefix):
+        proposals = self._calculate_proposals()
+        selected = 0
+        if prefix is not None:
+            selected = self.env.prefix_value(prefix)
+        if 0 <= selected < len(proposals):
+            result = self.env._completion_text(proposals[selected])
+        else:
+            self.env.message('Not enough proposals!')
+            return
+        self._apply_assist(result)
+
+    def auto_import(self):
+        if not self.interface._check_autoimport():
+            return
+        name = self.env.current_word()
+        modules = self.autoimport.get_modules(name)
+        if modules:
+            if len(modules) == 1:
+                module = modules[0]
+            else:
+                module = self.env.ask_values(
+                    'Which module to import: ', modules)
+            self._insert_import(name, module)
+        else:
+            self.env.message('Global name %s not found!' % name)
+
+    def completions(self):
+        proposals = self._calculate_proposals()
+        prefix = self.offset - self.starting_offset
+        return [self.env._completion_text(proposal)[prefix:]
+                for proposal in proposals]
+
+    def extended_completions(self):
+        proposals = self._calculate_proposals()
+        prefix = self.offset - self.starting_offset
+        return [[proposal.name[prefix:], proposal.get_doc(),
+                 proposal.type] for proposal in proposals]
+
+    def _apply_assist(self, assist):
+        if ' : ' in assist:
+            name, module = assist.rsplit(' : ', 1)
+            self.env.delete(self.starting_offset + 1, self.offset + 1)
+            self.env.insert(name)
+            self._insert_import(name, module)
+        else:
+            self.env.delete(self.starting_offset + 1, self.offset + 1)
+            self.env.insert(assist)
+
+    def _calculate_proposals(self):
+        self.interface._check_project()
+        resource = self.interface.resource
+        maxfixes = self.env.get('codeassist_maxfixes')
+        proposals = codeassist.code_assist(
+            self.interface.project, self.source, self.offset,
+            resource, maxfixes=maxfixes)
+        if self.env.get('sorted_completions', True):
+            proposals = codeassist.sorted_proposals(proposals)
+        if self.autoimport is not None:
+            if self.starting.strip() and '.' not in self.expression:
+                import_assists = self.autoimport.import_assist(self.starting)
+                for assist in import_assists:
+                    p = codeassist.CompletionProposal(' : '.join(assist),
+                                                      'autoimport')
+                    proposals.append(p)
+        return proposals
+
+    def _insert_import(self, name, module):
+        lineno = self.autoimport.find_insertion_line(self.source)
+        line = 'from %s import %s' % (module, name)
+        self.env.insert_line(line, lineno)
+
+    def _calculate_prefix(self, proposals):
+        if not proposals:
+            return ''
+        prefix = self.env._completion_text(proposals[0])
+        for proposal in proposals:
+            common = 0
+            name = self.env._completion_text(proposal)
+            for c1, c2 in zip(prefix, name):
+                if c1 != c2 or ' ' in (c1, c2):
+                    break
+                common += 1
+            prefix = prefix[:common]
+        return prefix
+
+    @property
+    @utils.cacheit
+    def offset(self):
+        return self.env.get_offset()
+
+    @property
+    @utils.cacheit
+    def source(self):
+        return self.interface._get_text()
+
+    @property
+    @utils.cacheit
+    def starting_offset(self):
+        return codeassist.starting_offset(self.source, self.offset)
+
+    @property
+    @utils.cacheit
+    def starting(self):
+        return self.source[self.starting_offset:self.offset]
+
+    @property
+    @utils.cacheit
+    def expression(self):
+        return codeassist.starting_expression(self.source, self.offset)
+
+    @property
+    def autoimport(self):
+        return self.interface.autoimport
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropemode/ropemode/refactor.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,491 @@
+import re
+
+import rope.base.change
+import rope.contrib.generate
+import rope.refactor.change_signature
+import rope.refactor.extract
+import rope.refactor.inline
+import rope.refactor.introduce_factory
+import rope.refactor.method_object
+import rope.refactor.move
+import rope.refactor.rename
+import rope.refactor.restructure
+import rope.refactor.usefunction
+from rope.base import taskhandle
+
+from ropemode import dialog, filter
+
+
+class Refactoring(object):
+    key = None
+    confs = {}
+    optionals = {}
+    saveall = True
+
+    def __init__(self, interface, env):
+        self.interface = interface
+        self.env = env
+
+    def show(self, initial_asking=True):
+        self.interface._check_project()
+        self.interface._save_buffers(only_current=not self.saveall)
+        self._create_refactoring()
+        action, result = dialog.show_dialog(
+            self.interface._askdata, ['perform', 'preview', 'cancel'],
+            self._get_confs(), self._get_optionals(),
+            initial_asking=initial_asking)
+        if action == 'cancel':
+            self.env.message('Cancelled!')
+            return
+        def calculate(handle):
+            return self._calculate_changes(result, handle)
+        name = 'Calculating %s changes' % self.name
+        changes = runtask(self.env, calculate, name=name)
+        if action == 'perform':
+            self._perform(changes)
+        if action == 'preview':
+            if changes is not None:
+                diffs = changes.get_description()
+                if self.env.preview_changes(diffs):
+                    self._perform(changes)
+                else:
+                    self.env.message('Thrown away!')
+            else:
+                self.env.message('No changes!')
+
+    @property
+    def project(self):
+        return self.interface.project
+
+    @property
+    def resource(self):
+        return self.interface._get_resource()
+
+    @property
+    def offset(self):
+        return self.env.get_offset()
+
+    @property
+    def region(self):
+        return self.env.get_region()
+
+    @property
+    def name(self):
+        return refactoring_name(self.__class__)
+
+    def _calculate_changes(self, option_values, task_handle):
+        pass
+
+    def _create_refactoring(self):
+        pass
+
+    def _done(self):
+        pass
+
+    def _perform(self, changes):
+        if changes is None:
+            self.env.message('No changes!')
+            return
+        def perform(handle, self=self, changes=changes):
+            self.project.do(changes, task_handle=handle)
+            self.interface._reload_buffers(changes)
+            self._done()
+        runtask(self.env, perform, 'Making %s changes' % self.name,
+                interrupts=False)
+        self.env.message(str(changes.description) + ' finished')
+
+    def _get_confs(self):
+        return self.confs
+
+    def _get_optionals(self):
+        return self.optionals
+
+    @property
+    def resources_option(self):
+        return dialog.Data('Files to apply this refactoring on: ',
+                           decode=self._decode_resources)
+
+    def _decode_resources(self, value):
+        return _resources(self.project, value)
+
+
+class Rename(Refactoring):
+    key = 'r'
+
+    saveall = True
+
+    def _create_refactoring(self):
+        self.renamer = rope.refactor.rename.Rename(
+            self.project, self.resource, self.offset)
+
+    def _calculate_changes(self, values, task_handle):
+        return self.renamer.get_changes(task_handle=task_handle, **values)
+
+    def _get_optionals(self):
+        opts = {}
+        opts['docs'] = dialog.Boolean('Search comments and docs: ', True)
+        if self.renamer.is_method():
+            opts['in_hierarchy'] = dialog.Boolean('Rename methods in '
+                                                  'class hierarchy: ')
+        opts['resources'] = self.resources_option
+        opts['unsure'] = dialog.Data('Unsure occurrences: ',
+                                     decode=self._decode_unsure,
+                                     values=['ignore', 'match'],
+                                     default='ignore')
+        return opts
+
+    def _get_confs(self):
+        oldname = str(self.renamer.get_old_name())
+        return {'new_name': dialog.Data('New name: ', default=oldname)}
+
+    def _decode_unsure(self, value):
+        unsure = value == 'match'
+        return lambda occurrence: unsure
+
+
+class RenameCurrentModule(Rename):
+    key = '1 r'
+    offset = None
+
+
+class Restructure(Refactoring):
+    key = 'x'
+    confs = {'pattern': dialog.Data('Restructuring pattern: '),
+             'goal': dialog.Data('Restructuring goal: ')}
+
+    def _calculate_changes(self, values, task_handle):
+        restructuring = rope.refactor.restructure.Restructure(
+            self.project, values['pattern'], values['goal'],
+            args=values['args'], imports=values['imports'])
+        return restructuring.get_changes(resources=values['resources'],
+                                         task_handle=task_handle)
+
+    def _get_optionals(self):
+        return {
+            'args': dialog.Data('Arguments: ', decode=self._decode_args),
+            'imports': dialog.Data('Imports: ', decode=self._decode_imports),
+            'resources': self.resources_option}
+
+    def _decode_args(self, value):
+        if value:
+            args = {}
+            for raw_check in value.split('\n'):
+                if raw_check:
+                    key, value = raw_check.split(':', 1)
+                    args[key.strip()] = value.strip()
+            return args
+
+    def _decode_imports(self, value):
+        if value:
+            return [line.strip() for line in value.split('\n')]
+
+
+class UseFunction(Refactoring):
+    key = 'u'
+
+    def _create_refactoring(self):
+        self.user = rope.refactor.usefunction.UseFunction(
+            self.project, self.resource, self.offset)
+
+    def _calculate_changes(self, values, task_handle):
+        return self.user.get_changes(task_handle=task_handle, **values)
+
+    def _get_optionals(self):
+        return {'resources': self.resources_option}
+
+
+class Move(Refactoring):
+    key = 'v'
+
+    def _create_refactoring(self):
+        self.mover = rope.refactor.move.create_move(self.project,
+                                                    self.resource,
+                                                    self.offset)
+
+    def _calculate_changes(self, values, task_handle):
+        destination = values['destination']
+        resources = values.get('resources', None)
+        if isinstance(self.mover, rope.refactor.move.MoveGlobal):
+            return self._move_global(destination, resources, task_handle)
+        if isinstance(self.mover, rope.refactor.move.MoveModule):
+            return self._move_module(destination, resources, task_handle)
+        if isinstance(self.mover, rope.refactor.move.MoveMethod):
+            return self._move_method(destination, resources, task_handle)
+
+    def _move_global(self, dest, resources, handle):
+        destination = self.project.pycore.find_module(dest)
+        return self.mover.get_changes(
+            destination, resources=resources, task_handle=handle)
+
+    def _move_method(self, dest, resources, handle):
+        return self.mover.get_changes(
+            dest, self.mover.get_method_name(),
+            resources=resources, task_handle=handle)
+
+    def _move_module(self, dest, resources, handle):
+        destination = self.project.pycore.find_module(dest)
+        return self.mover.get_changes(
+            destination, resources=resources, task_handle=handle)
+
+    def _get_confs(self):
+        if isinstance(self.mover, rope.refactor.move.MoveGlobal):
+            prompt = 'Destination module: '
+        if isinstance(self.mover, rope.refactor.move.MoveModule):
+            prompt = 'Destination package: '
+        if isinstance(self.mover, rope.refactor.move.MoveMethod):
+            prompt = 'Destination attribute: '
+        return {'destination': dialog.Data(prompt)}
+
+    def _get_optionals(self):
+        return {'resources': self.resources_option}
+
+
+class MoveCurrentModule(Move):
+    key = '1 v'
+    offset = None
+
+
+class ModuleToPackage(Refactoring):
+    key = '1 p'
+    saveall = False
+
+    def _create_refactoring(self):
+        self.packager = rope.refactor.ModuleToPackage(
+            self.project, self.resource)
+
+    def _calculate_changes(self, values, task_handle):
+        return self.packager.get_changes()
+
+
+class Inline(Refactoring):
+    key = 'i'
+
+    def _create_refactoring(self):
+        self.inliner = rope.refactor.inline.create_inline(
+            self.project, self.resource, self.offset)
+
+    def _calculate_changes(self, values, task_handle):
+        return self.inliner.get_changes(task_handle=task_handle, **values)
+
+    def _get_optionals(self):
+        opts = {'resources': self.resources_option}
+        if self.inliner.get_kind() == 'parameter':
+            opts['in_hierarchy'] = dialog.Boolean(
+                'Apply on all matching methods in class hierarchy: ', False)
+        else:
+            opts['remove'] = dialog.Boolean('Remove the definition: ', True)
+            opts['only_current'] = dialog.Boolean('Inline this '
+                                                  'occurrence only: ')
+        return opts
+
+
+class _Extract(Refactoring):
+    saveall = False
+    optionals = {'similar': dialog.Boolean('Extract similar pieces: ', True),
+                 'global_': dialog.Boolean('Make global: ')}
+    kind = None
+    constructor = None
+
+    def _create_refactoring(self):
+        start, end = self.region
+        self.extractor = self.constructor(self.project,
+                                          self.resource, start, end)
+
+    def _calculate_changes(self, values, task_handle):
+        similar = values.get('similar')
+        global_ = values.get('global_')
+        return self.extractor.get_changes(values['name'], similar=similar,
+                                          global_=global_)
+
+    def _get_confs(self):
+        return {'name': dialog.Data('Extracted %s name: ' % self.kind)}
+
+
+class ExtractVariable(_Extract):
+    key = 'l'
+    kind = 'variable'
+    constructor = rope.refactor.extract.ExtractVariable
+
+
+class ExtractMethod(_Extract):
+    key = 'm'
+    kind = 'method'
+    constructor = rope.refactor.extract.ExtractMethod
+
+
+class OrganizeImports(Refactoring):
+    key = 'o'
+    saveall = False
+
+    def _create_refactoring(self):
+        self.organizer = rope.refactor.ImportOrganizer(self.project)
+
+    def _calculate_changes(self, values, task_handle):
+        return self.organizer.organize_imports(self.resource)
+
+
+class MethodObject(Refactoring):
+    saveall = False
+    confs = {'classname': dialog.Data('New class name: ',
+                                      default='_ExtractedClass')}
+
+    def _create_refactoring(self):
+        self.objecter = rope.refactor.method_object.MethodObject(
+            self.project, self.resource, self.offset)
+
+    def _calculate_changes(self, values, task_handle):
+        classname = values.get('classname')
+        return self.objecter.get_changes(classname)
+
+
+class IntroduceFactory(Refactoring):
+    saveall = True
+    key = 'f'
+
+    def _create_refactoring(self):
+        self.factory = rope.refactor.introduce_factory.IntroduceFactory(
+            self.project, self.resource, self.offset)
+
+    def _calculate_changes(self, values, task_handle):
+        return self.factory.get_changes(task_handle=task_handle, **values)
+
+    def _get_confs(self):
+        default = 'create_%s' % self.factory.old_name.lower()
+        return {'factory_name': dialog.Data('Factory name: ', default)}
+
+    def _get_optionals(self):
+        return {'global_factory': dialog.Boolean('Make global: ', True),
+                'resources': self.resources_option}
+
+
+class ChangeSignature(Refactoring):
+    saveall = True
+    key = 's'
+
+    def _create_refactoring(self):
+        self.changer = rope.refactor.change_signature.ChangeSignature(
+            self.project, self.resource, self.offset)
+
+    def _calculate_changes(self, values, task_handle):
+        signature = values.get('signature')
+        args = re.sub(r'[\s\(\)]+', '', signature).split(',')
+        olds = [arg[0] for arg in self._get_args()]
+
+        changers = []
+        for arg in list(olds):
+            if arg in args:
+                continue
+            changers.append(rope.refactor.change_signature.
+                            ArgumentRemover(olds.index(arg)))
+            olds.remove(arg)
+
+        order = []
+        for index, arg in enumerate(args):
+            if arg not in olds:
+                changers.append(rope.refactor.change_signature.
+                                ArgumentAdder(index, arg))
+                olds.insert(index, arg)
+            order.append(olds.index(arg))
+        changers.append(rope.refactor.change_signature.
+                        ArgumentReorderer(order, autodef='None'))
+
+        del values['signature']
+        return self.changer.get_changes(changers, task_handle=task_handle,
+                                        **values)
+
+    def _get_args(self):
+        if hasattr(self.changer, 'get_args'):
+            return self.changer.get_args()
+        return self.changer.get_definition_info().args_with_defaults
+
+    def _get_confs(self):
+        args = []
+        for arg, default in self._get_args():
+            args.append(arg)
+        signature = '(' + ', '.join(args) + ')'
+        return {'signature': dialog.Data('Change the signature: ',
+                                         default=signature)}
+
+    def _get_optionals(self):
+        opts = {'resources': self.resources_option}
+        if self.changer.is_method():
+            opts['in_hierarchy'] = dialog.Boolean('Rename methods in '
+                                                  'class hierarchy: ')
+        return opts
+
+
+class _GenerateElement(Refactoring):
+
+    def _create_refactoring(self):
+        kind = self.name.split('_')[-1]
+        self.generator = rope.contrib.generate.create_generate(
+            kind, self.project, self.resource, self.offset)
+
+    def _calculate_changes(self, values, task_handle):
+        return self.generator.get_changes()
+
+    def _done(self):
+        resource, lineno = self.generator.get_location()
+        self.interface._goto_location(resource, lineno)
+
+
+class GenerateVariable(_GenerateElement):
+    key = 'n v'
+
+
+class GenerateFunction(_GenerateElement):
+    key = 'n f'
+
+
+class GenerateClass(_GenerateElement):
+    key = 'n c'
+
+
+class GenerateModule(_GenerateElement):
+    key = 'n m'
+
+
+class GeneratePackage(_GenerateElement):
+    key = 'n p'
+
+
+def refactoring_name(refactoring):
+    classname = refactoring.__name__
+    result = []
+    for c in classname:
+        if result and c.isupper():
+            result.append('_')
+        result.append(c.lower())
+    name = ''.join(result)
+    return name
+
+def _resources(project, text):
+    if text is None or text.strip() == '':
+        return None
+    return filter.resources(project, text)
+
+
+def runtask(env, command, name, interrupts=True):
+    return RunTask(env, command, name, interrupts)()
+
+class RunTask(object):
+
+    def __init__(self, env, task, name, interrupts=True):
+        self.env = env
+        self.task = task
+        self.name = name
+        self.interrupts = interrupts
+
+    def __call__(self):
+        handle = taskhandle.TaskHandle(name=self.name)
+        progress = self.env.create_progress(self.name)
+        def update_progress():
+            jobset = handle.current_jobset()
+            if jobset:
+                percent = jobset.get_percent_done()
+                if percent is not None:
+                    progress.update(percent)
+        handle.add_observer(update_progress)
+        result = self.task(handle)
+        progress.done()
+        return result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropemode/ropemodetest.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,122 @@
+import unittest
+
+from ropemode import dialog
+
+
+class ConfigTest(unittest.TestCase):
+
+    def setUp(self):
+        super(ConfigTest, self).setUp()
+
+    def tearDown(self):
+        super(ConfigTest, self).tearDown()
+
+    def test_trivial_case(self):
+        action, confs = dialog.show_dialog(_MockAskConfig(['done']), ['done'])
+        self.assertEquals('done', action)
+        self.assertEquals({}, confs)
+
+    def test_asking_normal_configs(self):
+        confs = {'name': dialog.Data()}
+        minibuffer = _MockAskConfig(['value', 'done'])
+        action, result = dialog.show_dialog(minibuffer,
+                                            ['done', 'cancel'], confs)
+        self.assertEquals({'name': 'value'}, result)
+        self.assertEquals('done', action)
+
+    def test_optional_confs(self):
+        optionals = {'name': dialog.Data()}
+        minibuffer = _MockAskConfig(['done'])
+        action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'],
+                                            optionals=optionals)
+        self.assertEquals(None, result.get('name', None))
+        self.assertEquals('done', action)
+
+    def test_optional_confs2(self):
+        optionals = {'name': dialog.Data()}
+        minibuffer = _MockAskConfig(['name', 'value', 'done'])
+        action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'],
+                                            optionals=optionals)
+        self.assertEquals({'name': 'value'}, result)
+        self.assertEquals('done', action)
+
+    def test_trivial_batchset(self):
+        optionals = {'name': dialog.Data()}
+        minibuffer = _MockAskConfig(['batchset', 'name value', 'done'])
+        action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'],
+                                            optionals=optionals)
+        self.assertEquals({'name': 'value'}, result)
+        self.assertEquals('done', action)
+
+    def test_batchset_multiple_sets(self):
+        optionals = {'name1': dialog.Data(), 'name2': dialog.Data()}
+        minibuffer = _MockAskConfig(['batchset',
+                                     'name1 value1\nname2 value2', 'done'])
+        action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'],
+                                            optionals=optionals)
+        self.assertEquals({'name1': 'value1', 'name2': 'value2'}, result)
+        self.assertEquals('done', action)
+
+    def test_multiline_sets(self):
+        optionals = {'name': dialog.Data()}
+        minibuffer = _MockAskConfig(
+            ['batchset', 'name\n line1\n  line2\n', 'done'])
+        action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'],
+                                            optionals=optionals)
+        self.assertEquals({'name': 'line1\n line2\n'}, result)
+        self.assertEquals('done', action)
+
+    def test_complex_batchset(self):
+        optionals = {'name1': dialog.Data(), 'name2': dialog.Data(),
+                     'name3': dialog.Data()}
+        minibuffer = _MockAskConfig(
+            ['batchset', 'name3\n value3\nname1\n line1\n  '
+             'line2\n\nname2 value2\n', 'done'])
+        action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'],
+                                            optionals=optionals)
+        self.assertEquals(
+            {'name1': 'line1\n line2\n', 'name2': 'value2',
+             'name3': 'value3\n'}, result)
+        self.assertEquals('done', action)
+
+    def test_skipping_blanks(self):
+        optionals = {'name1': dialog.Data(), 'name2': dialog.Data()}
+        minibuffer = _MockAskConfig(
+            ['batchset', '\nname1\n value1\n\nname2 value2\n\n', 'done'])
+        action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'],
+                                            optionals=optionals)
+        self.assertEquals({'name1': 'value1\n', 'name2': 'value2'}, result)
+        self.assertEquals('done', action)
+
+    def test_skip_initial_asking(self):
+        confs = {'name': dialog.Data()}
+        minibuffer = _MockAskConfig(
+            ['name', 'value', 'done'])
+        action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'],
+                                            confs=confs, initial_asking=False)
+        self.assertEquals({'name': 'value'}, result)
+        self.assertEquals('done', action)
+
+    def test_ignoring_trailing_colon_in_config_names(self):
+        optionals = {'name1': dialog.Data()}
+        minibuffer = _MockAskConfig(
+            ['batchset', 'name1: value1\n', 'done'])
+        action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'],
+                                            optionals=optionals)
+        self.assertEquals({'name1': 'value1'}, result)
+        self.assertEquals('done', action)
+
+
+class _MockAskConfig(object):
+
+    def __init__(self, responses=[]):
+        self.responses = responses
+        self.asked = []
+
+    def __call__(self, config, starting=None):
+        self.asked.append(config)
+        return self.responses[len(self.asked) - 1]
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropemode/setup.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,35 @@
+extra_kwargs = {}
+try:
+    from setuptools import setup
+    extra_kwargs['install_requires'] = ['rope >= 0.9.2']
+except ImportError:
+    from distutils.core import setup
+
+import ropemode
+
+
+classifiers=[
+    'Development Status :: 4 - Beta',
+    'Operating System :: OS Independent',
+    'Environment :: X11 Applications',
+    'Environment :: Win32 (MS Windows)',
+    'Environment :: MacOS X',
+    'Intended Audience :: Developers',
+    'License :: OSI Approved :: GNU General Public License (GPL)',
+    'Natural Language :: English',
+    'Programming Language :: Python',
+    'Topic :: Software Development']
+
+setup(name='ropemode',
+      version=ropemode.VERSION,
+      description=ropemode.INFO,
+      author='Ali Gholami Rudi',
+      author_email='aligrudi@users.sourceforge.net',
+      url='http://rope.sf.net/',
+      packages=['ropemode'],
+      license='GNU GPL',
+      classifiers=classifiers,
+      requires=['rope (>= 0.9.2)'],
+      **extra_kwargs
+)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropevim/.hgtags	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,4 @@
+dd2506d135c323e95f1033c488817ade2d1fbbc1 0.1
+43dcf217265c3beba85c7fe0b139df9d8b167ced 0.2c1
+f548c711e86af8cc62c0fc9df186516c416a4f22 0.2
+511c3b16f57c785b0e9fdc8d095e6325684e7415 0.3-rc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropevim/CONTRIBUTORS	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,9 @@
+======================
+ Ropevim Contributors
+======================
+
+* Alon Levy <alonlevy1@gmail.com>
+* Matthieu Tanguay-Carel <matthieutc@gmail.com>
+* Jesse Zhang <sbjesse@gmail.com>
+* Ben Davis <bendavis78@gmail.com>
+* Anton Gritsay <general@angri.ru>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropevim/COPYING	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  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.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the 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 a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE 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.
+
+		     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
+convey 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 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.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision 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, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This 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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropevim/MANIFEST.in	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,4 @@
+include README.txt COPYING setup.py MANIFEST.in
+include ropevim.py ropevim.vim
+recursive-include ropemode *.py
+recursive-include docs *.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropevim/README.txt	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,337 @@
+======================
+ ropevim, rope in vim
+======================
+
+Ropevim is a vim mode that uses rope_ library to provide features like
+python refactorings and code-assists.  You should install rope_
+library before using ropevim.
+
+.. _rope: http://rope.sf.net/
+
+
+New Features
+============
+
+* improved support of multibyte sources
+* implemented `extended complete` feature (disabled by default)
+* ropemode is not the part of distribution now
+
+
+Setting Up
+==========
+
+First add ropevim folder to the ``PYTHONPATH`` (or install it using
+``python setup.py install``).
+
+Then load ``ropevim.vim`` in vim.  That can be done either by adding
+``source path/to/ropevim.vim`` to your ``~/.vimrc`` or copying it to
+``~/.vim/plugin/`` folder.
+
+If you don't want to install rope and ropevim you can add something
+like this to your ``~/.vimrc``::
+
+  let $PYTHONPATH .= ":/path/to/rope:/path/to/ropevim"
+  source /path/to/ropevim.vim
+
+For using the repository version of rope, see ``docs/ropevim.txt``.
+
+
+Getting Started
+===============
+
+Refactoring Dialog
+------------------
+
+Ropevim refactorings use a special kind of dialog.  Depending on the
+refactoring, you'll be asked about the essential information a
+refactoring needs to know (like the new name in rename refactoring).
+
+Next you'll see the base prompt of a refactoring dialog that shows
+something like "Choose what to do".  By entering the name of a
+refactoring option you can set its value.  After setting each option
+you'll be returned back to the base prompt.  Finally, you can ask rope
+to perform, preview or cancel the refactoring.
+
+See keybinding_ section and try the refactorings yourself.
+
+
+Finding Files
+-------------
+
+By using ``RopeFindFile`` (``C-x p f`` by default), you can search for
+files in your project.  When you complete the minibuffer you'll see
+all files in the project; files are shown as their reversed paths.
+For instance ``projectroot/docs/todo.txt`` is shown like
+``todo.txt<docs``.  This way you can find files faster in your
+project.  ``RopeFindFileOtherWindow`` (``C-x p 4 f``) opens the
+file in the other window.
+
+
+Code-Assist
+-----------
+
+``RopeCodeAssist`` command (``M-/``) will let you select from a list
+of completions.  ``RopeLuckyAssist`` command (``M-?``) does not ask
+anything; instead, it inserts the first proposal.
+
+You can tell ropevim to use vim's complete function in insert mode;
+Add::
+
+  let ropevim_vim_completion=1
+
+to your ``~/.vimrc`` file.
+
+Note that when this variable is set, autoimport completions no longer
+work since they need to insert an import to the top of the module, too.
+
+By default autocomplete feature will use plain list of proposed completion
+items. You can enable showing extended information about completion
+proposals by setting ::
+
+  let ropevim_extended_complete=1
+
+Completion menu list will show the proposed name itself, one letter which
+shows where this proposal came from (it can be "L" for locals, "G" for
+globals, "B" for builtins, or empty string if such scope definition is not
+applicable), a short object type description (such as "func", "param",
+"meth" and so forth) and a first line of proposed object's docstring (if it
+has one). For function's keyword parameters the last field shows "*" symbol
+if this param is required or "= <default value>" if it is not.
+
+Note that you'll need rope r1558:0d76aa9d0614 or later and ropemode
+r35:bd77ca42b04d or later for extended complete feature to work.
+
+
+Enabling Autoimport
+-------------------
+
+Rope can propose and automatically import global names in other
+modules.  Rope maintains a cache of global names for each project.  It
+updates the cache only when modules are changed; if you want to cache
+all your modules at once, use ``RopeGenerateAutoimportCache``.  It
+will cache all of the modules inside the project plus those whose
+names are listed in ``ropevim_autoimport_modules`` list::
+
+  # add the name of modules you want to autoimport
+  let g:ropevim_autoimport_modules = ["os", "shutil"]
+
+Now if you are in a buffer that contains::
+
+  rmtree
+
+and you execute ``RopevimAutoImport`` you'll end up with::
+
+  from shutil import rmtree
+  rmtree
+
+Also ``RopeCodeAssist`` and ``RopeLuckyAssist`` propose auto-imported
+names by using ``name : module`` style.  Selecting them will import
+the module automatically.
+
+
+Filtering Resources
+-------------------
+
+Some refactorings, restructuring and find occurrences take an option
+called resources.  This option can be used to limit the resources on
+which a refactoring should be applied.
+
+It uses a simple format: each line starts with either '+' or '-'.
+Each '+' means include the file (or its children if it's a folder)
+that comes after it.  '-' has the same meaning for exclusion.  So
+using::
+
+  +rope
+  +ropetest
+  -rope/contrib
+
+means include all python files inside ``rope`` and ``ropetest``
+folders and their subfolder, but those that are in ``rope/contrib``.
+Or::
+
+  -ropetest
+  -setup.py
+
+means include all python files inside the project but ``setup.py`` and
+those under ``ropetest`` folder.
+
+
+Finding Occurrences
+-------------------
+
+The find occurrences command (``C-c f`` by default) can be used to
+find the occurrences of a python name.  If ``unsure`` option is
+``yes``, it will also show unsure occurrences; unsure occurrences are
+indicated with a ``?`` mark in the end.  Note that ropevim uses the
+quickfix feature of vim for marking occurrence locations.
+
+
+Dialog ``batchset`` Command
+---------------------------
+
+When you use ropevim dialogs there is a command called ``batchset``.
+It can set many options at the same time.  After selecting this
+command from dialog base prompt, you are asked to enter a string.
+
+``batchset`` strings can set the value of configs in two ways.  The
+single line form is like this::
+
+  name1 value1
+  name2 value2
+
+That is the name of config is followed its value.  For multi-line
+values you can use::
+
+  name1
+   line1
+   line2
+
+  name2
+   line3
+
+Each line of the definition should start with a space or a tab.  Note
+that blank lines before the name of config definitions are ignored.
+
+``batchset`` command is useful when performing refactorings with long
+configs, like restructurings::
+
+  pattern ${pycore}.create_module(${project}.root, ${name})
+
+  goal generate.create_module(${project}, ${name})
+
+  imports
+   from rope.contrib import generate
+
+  args
+   pycore: type=rope.base.pycore.PyCore
+   project: type=rope.base.project.Project
+
+.. ignore the two-space indents
+
+This is a valid ``batchset`` string for restructurings.
+
+Just for the sake of completeness, the reverse of the above
+restructuring can be::
+
+  pattern ${create_module}(${project}, ${name})
+
+  goal ${project}.pycore.create_module(${project}.root, ${name})
+
+  args
+   create_module: name=rope.contrib.generate.create_module
+   project: type=rope.base.project.Project
+
+
+Variables
+=========
+
+* ``ropevim_codeassist_maxfixes``: The maximum number of syntax errors
+  to fix for code assists.  The default value is ``1``.
+* ``ropevim_local_prefix``: The prefix for ropevim refactorings.
+  Defaults to ``C-c r``.
+* ``ropevim_global_prefix``: The prefix for ropevim project commands
+  Defaults to ``C-x p``.
+* ``ropevim_enable_shortcuts``: Shows whether to bind ropevim
+  shortcuts keys.  Defaults to ``1``.
+* ``ropevim_guess_project``: If non-zero, ropevim tries to guess and
+  open the project that contains the file on which a ropevim command
+  is performed when no project is already open.
+
+* ``ropevim_enable_autoimport``: Shows whether to enable autoimport.
+* ``ropevim_autoimport_modules``: The name of modules whose global
+  names should be cached.  `RopeGenerateAutoimportCache' reads this
+  list and fills its cache.
+* ``ropevim_autoimport_underlineds``: If set, autoimport will cache
+  names starting with underlines, too.
+
+* ``ropevim_goto_def_newwin``: If set, ropevim will open a new buffer
+  for "go to definition" result if the definition found is located
+  in another file. By default the file is open in the same buffer.
+
+
+Keybinding
+==========
+
+Uses almost the same keybinding as ropemacs.  Note that global
+commands have a ``C-x p`` prefix and local commands have a ``C-c r``
+prefix.  You can change that (see variables_ section).
+
+================  ============================
+Key               Command
+================  ============================
+C-x p o           RopeOpenProject
+C-x p k           RopeCloseProject
+C-x p f           RopeFindFile
+C-x p 4 f         RopeFindFileOtherWindow
+C-x p u           RopeUndo
+C-x p r           RopeRedo
+C-x p c           RopeProjectConfig
+C-x p n [mpfd]    RopeCreate(Module|Package|File|Directory)
+                  RopeWriteProject
+
+C-c r r           RopeRename
+C-c r l           RopeExtractVariable
+C-c r m           RopeExtractMethod
+C-c r i           RopeInline
+C-c r v           RopeMove
+C-c r x           RopeRestructure
+C-c r u           RopeUseFunction
+C-c r f           RopeIntroduceFactory
+C-c r s           RopeChangeSignature
+C-c r 1 r         RopeRenameCurrentModule
+C-c r 1 v         RopeMoveCurrentModule
+C-c r 1 p         RopeModuleToPackage
+
+C-c r o           RopeOrganizeImports
+C-c r n [vfcmp]   RopeGenerate(Variable|Function|Class|Module|Package)
+
+C-c r a /         RopeCodeAssist
+C-c r a g         RopeGotoDefinition
+C-c r a d         RopeShowDoc
+C-c r a f         RopeFindOccurrences
+C-c r a ?         RopeLuckyAssist
+C-c r a j         RopeJumpToGlobal
+C-c r a c         RopeShowCalltip
+                  RopeAnalyzeModule
+
+                  RopeAutoImport
+                  RopeGenerateAutoimportCache
+===============   ============================
+
+
+Shortcuts
+---------
+
+Some commands are used very frequently; specially the commands in
+code-assist group.  You can define your own shortcuts like this::
+
+  :map <C-c>g :call RopeGotoDefinition()
+
+Ropevim itself comes with a few shortcuts.  These shortcuts will be
+used only when ``ropevim_enable_shortcuts`` is set.
+
+================  ============================
+Key               Command
+================  ============================
+M-/               RopeCodeAssist
+M-?               RopeLuckyAssist
+C-c g             RopeGotoDefinition
+C-c d             RopeShowDoc
+C-c f             RopeFindOccurrences
+================  ============================
+
+
+Contributing
+============
+
+Send your bug reports, feature requests and patches to `rope-dev (at)
+googlegroups.com`_.
+
+.. _`rope-dev (at) googlegroups.com`: http://groups.google.com/group/rope-dev
+
+
+License
+=======
+
+This program is under the terms of GPL (GNU General Public License).
+Have a look at ``COPYING`` file for more information.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropevim/docs/done.txt	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,28 @@
+======
+ Done
+======
+
+> Public Release 0.3 : Febrary 5, 2010
+
+* ropemode is not the part of distribution : Febrary 5, 2010
+* implemented `extended complete` feature : January 26, 2010
+* improved support of multibyte sources : June 24, 2009
+
+> Public Release 0.2 : October 3, 2008
+
+* fixed quickfix error format : August 18, 2008
+* ropevim_guess_project variable : June 18, 2008
+
+> Public Release 0.2c1 : June 12, 2008
+
+* not showing python traceback for bad inputs : May 23, 2008
+* interrupting refactorings : May 22, 2008
+
+> Public Release 0.1 : May 22, 2008
+
+* ropvim menu : May 21, 2008
+* code-assist in insert mode : May 21, 2008
+* using vim quickfix for showing occurrences : May 20, 2008
+* better dialogs : May 19, 2008
+* implementing basic ropemode commands : May 15, 2008
+* project started! : May 12, 2008
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropevim/docs/ropevim.txt	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,77 @@
+======================
+ ropevim, rope in vim
+======================
+
+Ropevim is a plugin for performing python refactorings in vim.  It
+uses rope_ library.
+
+You should install `rope`_ library before using ropevim.  You can
+download ropevim from `project download page`_.
+
+.. _rope: http://rope.sf.net/
+
+
+Features
+========
+
+* Supports many of the refactorings that are supported by rope_
+  library:
+
+  * Rename
+  * Extract method/local variable
+  * Move class/function/module/package/method
+  * Inline method/local variable/parameter
+  * Restructuring
+  * Change signature
+  * ...
+
+* Other refactoring-related features
+
+  * Previewing refactorings
+  * Undo/redo refactorings
+  * Showing refactoring progress
+
+* Code-assists
+
+  * Code-completion
+  * Goto definition
+  * Show pydoc
+  * Find occurrences
+  * Organize imports (remove unused and duplicate imports and sort them)
+  * Generating python elements
+
+
+Source Repository
+=================
+
+The repository version needs ropemode (which was once part of
+ropemacs); in order to use the repository version of ropevim you need
+to put ropemode in your ``PYTHONPATH``.  Note that ropemode is
+included in released packages.
+
+Ropevim:
+
+* repo url: http://bitbucket.org/agr/ropevim
+* snapshot: http://bitbucket.org/agr/ropevim/get/tip.gz
+
+Ropemode:
+
+* repo url: http://bitbucket.org/agr/ropemode
+* snapshot: http://bitbucket.org/agr/ropemode/get/tip.gz
+
+
+Feedback
+========
+
+Send your bug reports, feature requests and patches to `rope-dev (at)
+googlegroups.com`_.
+
+
+License
+=======
+
+Ropevim is under the terms of GNU GPL (GNU General Public License).
+
+.. _project download page: http://sf.net/projects/rope/files
+.. _`rope-dev (at) googlegroups.com`: http://groups.google.com/group/rope-dev
+.. _Mercurial: http://selenic.com/mercurial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropevim/docs/todo.txt	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,8 @@
+==============
+ Ropevim TODO
+==============
+
+* preventing changed file warnings
+* interrupting refactorings
+* better progress bar
+* prefixing functions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropevim/ropevim.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,459 @@
+"""ropevim, a vim mode for using rope refactoring library"""
+import os
+import tempfile
+import re
+
+import ropemode.decorators
+import ropemode.environment
+import ropemode.interface
+
+import vim
+
+
+class VimUtils(ropemode.environment.Environment):
+
+    def ask(self, prompt, default=None, starting=None):
+        if starting is None:
+            starting = ''
+        if default is not None:
+            prompt = prompt + ('[%s] ' % default)
+        result = call('input("%s", "%s")' % (prompt, starting))
+        if default is not None and result == '':
+            return default
+        return result
+
+    def ask_values(self, prompt, values, default=None,
+                   starting=None, show_values=None):
+        if show_values or (show_values is None and len(values) < 14):
+            self._print_values(values)
+        if default is not None:
+            prompt = prompt + ('[%s] ' % default)
+        starting = starting or ''
+        _completer.values = values
+        answer = call('input("%s", "%s", "customlist,RopeValueCompleter")' %
+                      (prompt, starting))
+        if answer is None:
+            if 'cancel' in values:
+                return 'cancel'
+            return
+        if default is not None and not answer:
+            return default
+        if answer.isdigit() and 0 <= int(answer) < len(values):
+            return values[int(answer)]
+        return answer
+
+    def _print_values(self, values):
+        numbered = []
+        for index, value in enumerate(values):
+            numbered.append('%s. %s' % (index, str(value)))
+        echo('\n'.join(numbered) + '\n')
+
+    def ask_directory(self, prompt, default=None, starting=None):
+        return call('input("%s", ".", "dir")' % prompt)
+
+    def ask_completion(self, prompt, values, starting=None):
+        if self.get('vim_completion') and 'i' in call('mode()'):
+            if not self.get('extended_complete', False):
+                proposals = u','.join(u"'%s'" % self._completion_text(proposal)
+                                      for proposal in values)
+            else:
+                proposals = u','.join(self._extended_completion(proposal)
+                                      for proposal in values)
+
+            col = int(call('col(".")'))
+            if starting:
+                col -= len(starting)
+            command = u'call complete(%s, [%s])' % (col, proposals)
+            vim.command(command.encode(self._get_encoding()))
+            return None
+        return self.ask_values(prompt, values, starting=starting,
+                               show_values=False)
+
+    def message(self, message):
+        echo(message)
+
+    def yes_or_no(self, prompt):
+        return self.ask_values(prompt, ['yes', 'no']) == 'yes'
+
+    def y_or_n(self, prompt):
+        return self.yes_or_no(prompt)
+
+    def get(self, name, default=None):
+        vimname = 'g:ropevim_%s' % name
+        if str(vim.eval('exists("%s")' % vimname)) == '0':
+            return default
+        result = vim.eval(vimname)
+        if isinstance(result, str) and result.isdigit():
+            return int(result)
+        return result
+
+    def get_offset(self):
+        result = self._position_to_offset(*self.cursor)
+        return result
+
+    def _get_encoding(self):
+        return vim.eval('&encoding')
+    def _encode_line(self, line):
+        return line.encode(self._get_encoding())
+    def _decode_line(self, line):
+        return line.decode(self._get_encoding())
+
+    def _position_to_offset(self, lineno, colno):
+        result = min(colno, len(self.buffer[lineno -1]) + 1)
+        for line in self.buffer[:lineno-1]:
+            line = self._decode_line(line)
+            result += len(line) + 1
+        return result
+
+    def get_text(self):
+        return self._decode_line('\n'.join(self.buffer)) + u'\n'
+
+    def get_region(self):
+        start = self._position_to_offset(*self.buffer.mark('<'))
+        end = self._position_to_offset(*self.buffer.mark('>'))
+        return start, end
+
+    @property
+    def buffer(self):
+        return vim.current.buffer
+
+    def _get_cursor(self):
+        lineno, col = vim.current.window.cursor
+        line = self._decode_line(vim.current.line[:col])
+        col = len(line)
+        return (lineno, col)
+
+    def _set_cursor(self, cursor):
+        lineno, col = cursor
+        line = self._decode_line(vim.current.line)
+        line = self._encode_line(line[:col])
+        col = len(line)
+        vim.current.window.cursor = (lineno, col)
+
+    cursor = property(_get_cursor, _set_cursor)
+
+    def filename(self):
+        return self.buffer.name
+
+    def is_modified(self):
+        return vim.eval('&modified')
+
+    def goto_line(self, lineno):
+        self.cursor = (lineno, 0)
+
+    def insert_line(self, line, lineno):
+        self.buffer[lineno - 1:lineno - 1] = [line]
+
+    def insert(self, text):
+        lineno, colno = self.cursor
+        line = self.buffer[lineno - 1]
+        self.buffer[lineno - 1] = line[:colno] + text + line[colno:]
+        self.cursor = (lineno, colno + len(text))
+
+    def delete(self, start, end):
+        lineno1, colno1 = self._offset_to_position(start - 1)
+        lineno2, colno2 = self._offset_to_position(end - 1)
+        lineno, colno = self.cursor
+        if lineno1 == lineno2:
+            line = self.buffer[lineno1 - 1]
+            self.buffer[lineno1 - 1] = line[:colno1] + line[colno2:]
+            if lineno == lineno1 and colno >= colno1:
+                diff = colno2 - colno1
+                self.cursor = (lineno, max(0, colno - diff))
+
+    def _offset_to_position(self, offset):
+        text = self.get_text()
+        lineno = text.count('\n', 0, offset) + 1
+        try:
+            colno = offset - text.rindex('\n', 0, offset) - 1
+        except ValueError:
+            colno = offset
+        return lineno, colno
+
+    def filenames(self):
+        result = []
+        for buffer in vim.buffers:
+            if buffer.name:
+                result.append(buffer.name)
+        return result
+
+    def save_files(self, filenames):
+        vim.command('wall')
+
+    def reload_files(self, filenames, moves={}):
+        initial = self.filename()
+        for filename in filenames:
+            self.find_file(moves.get(filename, filename), force=True)
+        if initial:
+            self.find_file(initial)
+
+    def find_file(self, filename, readonly=False, other=False, force=False):
+        if filename != self.filename() or force:
+            if other:
+                vim.command('new')
+            vim.command('e %s' % filename)
+            if readonly:
+                vim.command('set nomodifiable')
+
+    def create_progress(self, name):
+        return VimProgress(name)
+
+    def current_word(self):
+        return vim.eval('expand("<cword>")')
+
+    def push_mark(self):
+        vim.command('mark `')
+
+    def prefix_value(self, prefix):
+        return prefix
+
+    def show_occurrences(self, locations):
+        self._quickfixdefs(locations)
+
+    def _quickfixdefs(self, locations):
+        filename = os.path.join(tempfile.gettempdir(), tempfile.mktemp())
+        try:
+            self._writedefs(locations, filename)
+            vim.command('let old_errorfile = &errorfile')
+            vim.command('let old_errorformat = &errorformat')
+            vim.command('set errorformat=%f:%l:\ %m')
+            vim.command('cfile ' + filename)
+            vim.command('let &errorformat = old_errorformat')
+            vim.command('let &errorfile = old_errorfile')
+        finally:
+            os.remove(filename)
+
+    def _writedefs(self, locations, filename):
+        tofile = open(filename, 'w')
+        try:
+            for location in locations:
+                err = '%s:%d: - %s\n' % (location.filename,
+                                         location.lineno, location.note)
+                echo(err)
+                tofile.write(err)
+        finally:
+            tofile.close()
+
+    def show_doc(self, docs, altview=False):
+        if docs:
+            echo(docs)
+
+    def preview_changes(self, diffs):
+        echo(diffs)
+        return self.y_or_n('Do the changes? ')
+
+    def local_command(self, name, callback, key=None, prefix=False):
+        self._add_command(name, callback, key, prefix,
+                          prekey=self.get('local_prefix'))
+
+    def global_command(self, name, callback, key=None, prefix=False):
+        self._add_command(name, callback, key, prefix,
+                          prekey=self.get('global_prefix'))
+
+    def add_hook(self, name, callback, hook):
+        mapping = {'before_save': 'FileWritePre,BufWritePre',
+                   'after_save': 'FileWritePost,BufWritePost',
+                   'exit': 'VimLeave'}
+        self._add_function(name, callback)
+        vim.command('autocmd %s *.py call %s()' %
+                    (mapping[hook], _vim_name(name)))
+
+    def _add_command(self, name, callback, key, prefix, prekey):
+        self._add_function(name, callback, prefix)
+        vim.command('command! -range %s call %s()' %
+                    (_vim_name(name), _vim_name(name)))
+        if key is not None:
+            key = prekey + key.replace(' ', '')
+            vim.command('map %s :call %s()<cr>' % (key, _vim_name(name)))
+
+    def _add_function(self, name, callback, prefix=False):
+        globals()[name] = callback
+        arg = 'None' if prefix else ''
+        vim.command('function! %s()\n' % _vim_name(name) +
+                    'python ropevim.%s(%s)\n' % (name, arg) +
+                    'endfunction\n')
+
+    def _completion_data(self, proposal):
+        return proposal
+
+    _docstring_re = re.compile('^[\s\t\n]*([^\n]*)')
+    def _extended_completion(self, proposal):
+        # we are using extended complete and return dicts instead of strings.
+        # `ci` means "completion item". see `:help complete-items`
+        ci = {'word': proposal.name}
+
+        scope = proposal.scope[0].upper()
+        type_ = proposal.type
+        info = None
+
+        if proposal.scope == 'parameter_keyword':
+            scope = ' '
+            type_ = 'param'
+            if not hasattr(proposal, 'get_default'):
+                # old version of rope
+                pass
+            else:
+                default = proposal.get_default()
+                if default is None:
+                    info = '*'
+                else:
+                    info = '= %s' % default
+
+        elif proposal.scope == 'keyword':
+            scope = ' '
+            type_ = 'keywd'
+
+        elif proposal.scope == 'attribute':
+            scope = 'M'
+            if proposal.type == 'function':
+                type_ = 'meth'
+            elif proposal.type == 'instance':
+                type_ = 'prop'
+
+        elif proposal.type == 'function':
+            type_ = 'func'
+
+        elif proposal.type == 'instance':
+            type_ = 'inst'
+
+        elif proposal.type == 'module':
+            type_ = 'mod'
+
+        if info is None:
+            obj_doc = proposal.get_doc()
+            if obj_doc:
+                info = self._docstring_re.match(obj_doc).group(1)
+            else:
+                info = ''
+
+        if type_ is None:
+            type_ = ' '
+        else:
+            type_ = type_.ljust(5)[:5]
+        ci['menu'] = ' '.join((scope, type_, info))
+        ret =  u'{%s}' % \
+               u','.join(u'"%s":"%s"' % \
+                         (key, value.replace('"', '\\"')) \
+                         for (key, value) in ci.iteritems())
+        return ret
+
+
+def _vim_name(name):
+    tokens = name.split('_')
+    newtokens = ['Rope'] + [token.title() for token in tokens]
+    return ''.join(newtokens)
+
+
+class VimProgress(object):
+
+    def __init__(self, name):
+        self.name = name
+        self.last = 0
+        echo('%s ... ' % self.name)
+
+    def update(self, percent):
+        try:
+            vim.eval('getchar(0)')
+        except vim.error:
+            raise KeyboardInterrupt('Task %s was interrupted!' % self.name)
+        if percent > self.last + 4:
+            echo('%s ... %s%%%%' % (self.name, percent))
+            self.last = percent
+
+    def done(self):
+        echo('%s ... done' % self.name)
+
+
+def echo(message):
+    if isinstance(message, unicode):
+        message = message.encode(vim.eval('&encoding'))
+    print message
+
+def call(command):
+    return vim.eval(command)
+
+
+class _ValueCompleter(object):
+
+    def __init__(self):
+        self.values = []
+        vim.command('python import vim')
+        vim.command('function! RopeValueCompleter(A, L, P)\n'
+                    'python args = [vim.eval("a:" + p) for p in "ALP"]\n'
+                    'python ropevim._completer(*args)\n'
+                    'return s:completions\n'
+                    'endfunction\n')
+
+    def __call__(self, arg_lead, cmd_line, cursor_pos):
+        result = [proposal.name for proposal in self.values \
+                  if proposal.name.startswith(arg_lead)]
+        vim.command('let s:completions = %s' % result)
+
+
+variables = {'ropevim_enable_autoimport': 1,
+             'ropevim_autoimport_underlineds': 0,
+             'ropevim_codeassist_maxfixes' : 1,
+             'ropevim_enable_shortcuts' : 1,
+             'ropevim_autoimport_modules': '[]',
+             'ropevim_confirm_saving': 0,
+             'ropevim_local_prefix': '"<C-c>r"',
+             'ropevim_global_prefix': '"<C-x>p"',
+             'ropevim_vim_completion': 0,
+             'ropevim_guess_project': 0}
+
+shortcuts = {'code_assist': '<M-/>',
+             'lucky_assist': '<M-?>',
+             'goto_definition': '<C-c>g',
+             'show_doc': '<C-c>d',
+             'find_occurrences': '<C-c>f'}
+
+insert_shortcuts = {'code_assist': '<M-/>',
+                    'lucky_assist': '<M-?>'}
+
+def _init_variables():
+    for variable, default in variables.items():
+        vim.command('if !exists("g:%s")\n' % variable +
+                    '  let g:%s = %s\n' % (variable, default))
+
+def _enable_shortcuts(env):
+    if env.get('enable_shortcuts'):
+        for command, shortcut in shortcuts.items():
+            vim.command('map %s :call %s()<cr>' %
+                        (shortcut, _vim_name(command)))
+        for command, shortcut in insert_shortcuts.items():
+            command_name = _vim_name(command) + 'InsertMode'
+            vim.command('func! %s()\n' % command_name +
+                        'call %s()\n' % _vim_name(command) +
+                        'return ""\n'
+                        'endfunc')
+            vim.command('imap %s <C-R>=%s()<cr>' % (shortcut, command_name))
+
+def _add_menu(env):
+    project = ['open_project', 'close_project', 'find_file', 'undo', 'redo']
+    refactor = ['rename', 'extract_variable', 'extract_method', 'inline',
+                'move', 'restructure', 'use_function', 'introduce_factory',
+                'change_signature', 'rename_current_module',
+                'move_current_module', 'module_to_package']
+    assists = ['code_assist', 'goto_definition', 'show_doc', 'find_occurrences',
+               'lucky_assist', 'jump_to_global', 'show_calltip']
+    vim.command('silent! aunmenu Ropevim')
+    for index, items in enumerate([project, assists, refactor]):
+        if index != 0:
+            vim.command('amenu <silent> &Ropevim.-SEP%s- :' % index)
+        for name in items:
+            item = '\ '.join(token.title() for token in name.split('_'))
+            for command in ['amenu', 'vmenu']:
+                vim.command('%s <silent> &Ropevim.%s :call %s()<cr>' %
+                            (command, item, _vim_name(name)))
+
+
+ropemode.decorators.logger.message = echo
+ropemode.decorators.logger.only_short = True
+_completer = _ValueCompleter()
+
+_init_variables()
+_env = VimUtils()
+_interface = ropemode.interface.RopeMode(env=_env)
+_interface.init()
+_enable_shortcuts(_env)
+_add_menu(_env)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropevim/ropevim.vim	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,7 @@
+function! LoadRope()
+python << EOF
+import ropevim
+EOF
+endfunction
+
+call LoadRope()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/sadness/ropevim/src/ropevim/setup.py	Wed Oct 06 12:30:46 2010 -0400
@@ -0,0 +1,41 @@
+extra_kwargs = {}
+try:
+    from setuptools import setup
+    extra_kwargs['install_requires'] = ['rope >= 0.9.3', 'ropemode']
+    extra_kwargs['zip_safe'] = False
+except ImportError:
+    from distutils.core import setup
+
+
+classifiers=[
+    'Development Status :: 4 - Beta',
+    'Operating System :: OS Independent',
+    'Environment :: X11 Applications',
+    'Environment :: Win32 (MS Windows)',
+    # Have not been tested on MacOS
+    # 'Environment :: MacOS X',
+    'Intended Audience :: Developers',
+    'License :: OSI Approved :: GNU General Public License (GPL)',
+    'Natural Language :: English',
+    'Programming Language :: Python',
+    'Topic :: Software Development']
+
+def get_long_description():
+    lines = open('README.txt').read().splitlines(False)
+    end = lines.index('Setting Up')
+    return '\n' + '\n'.join(lines[:end]) + '\n'
+
+setup(name='ropevim',
+      version='0.3-rc',
+      description='A vim plugin for using rope python refactoring library',
+      long_description=get_long_description(),
+      py_modules=['ropevim'],
+      author='Ali Gholami Rudi',
+      author_email='aligrudi@users.sourceforge.net',
+      url='http://rope.sf.net/ropevim.html',
+      license='GNU GPL',
+      classifiers=classifiers,
+      requires=['ropemode'],
+      data_files=[('share/vim/plugin', ['ropevim.vim'])],
+      **extra_kwargs
+)