1. Introduction {#sec1}
===============

Over thelast twenty years, the effort to produce new, more effective, and less toxic cytotoxic agents has been intensive, in order to ameliorate the treatment of cancer patients. One of the most effective agents since the late 1970s has been cisplatin (CDDP) in patients with testicular cancer \[[@B1]\], ovarian cancer \[[@B2]\], head and neck \[[@B3]\], and lung cancer \[[@B4]\] as well as bladder cancer \[[@B5]\] and in other malignancies \[[@B6], [@B7]\]. Cisplatin was established as being quite effective and as one of the most important cytotoxic agents. It has mainly been administered in combination with other agents. The toxicity rendered by cisplatin has been its main drawback, particularly nephrotoxicity \[[@B8]--[@B10]\]. After 1990, new agents that did not cause nephrotoxicity were produced as a substitute for cisplatin. Agents such as carboplatin \[[@B11]\] paclitaxel, docetaxel, gemcitabine, vinorelbine, and irinotecan \[[@B12]--[@B15]\] were used either in combination or as substitutes for cisplatin \[[@B16], [@B17]\]. These agents succeeded in producing no nephrotoxicity but did produce other toxicities such as myelotoxicity, in comparison to cisplatin. The main example was carboplatin, an analogue of cisplatin, which showed no renal toxicity but produced higher myelotoxicity than cisplatin. Carboplatin has often been used as a substitute for CDDP \[[@B11], [@B12]\] in lung \[[@B15]\], head and neck, and ovarian cancers \[[@B11]\]. The effectiveness of carboplatin was more or less equal to that of CDDP but not better. For instance, CDDP was shown to be more effective than carboplatin in the most common lung cancer, adenocarcinoma \[[@B18]\]. The other agents, previously mentioned, are mainly administered in combination with CDDP than as a substitute for it. Over all of the last twenty years, cisplatin has been in regular usage since most oncologists still believe it has priority with regard to effectiveness. Liposomal agents comprise another direction which research is taking and several of these have become part of clinical practice as is the case of liposomal anthracycline. None of these agents has managed to become a substitute for cisplatin, and they are used as second-line treatment.

Our review article is related to a new formulation of cisplatin, that is, liposomal cisplatin (lipoplatin). The purpose of this agent is to become a substitute for the original cisplatin, and, thus, the two drugs must be compared with regard to toxicity and effectiveness.

There are preclinical data in cancer cell cultures and in animals as well as clinical data which involve Phase I studies, pharmacokinetics and Phase II and Phase III studies. The data in 16 published studies are related to patients with pancreatic cancer, non-small-cell lung cancer (NSCLC), head and neck, and breast cancers.

2. Lipoplatin: Formulation, Mechanisms, and Technology {#sec2}
======================================================

Cisplatin was formulated into liposomes as depicted in [Figure 1](#fig1){ref-type="fig"}. The lipids of lipoplatin are composed of soy phosphatidyl choline (SPC-3), cholesterol, dipalmitoyl phosphatidyl glycerol (DPPG), and methoxy-polyethylene glycol-distearoyl phosphatidylethanolamine (mPEG 2000-DSPE). The formulation was achieved by the formation of reverse micelles between cisplatin and DPPG under special conditions of pH, ethanol, ionic strength, and other parameters, and the cisplatin-DPPG reverse micelles were subsequently converted into liposomes by interaction with neutral lipids. About 15 extrusions are performed to give to the nanoparticles their final size of 110 nm, using a thermobarrel, extruder and membranes of 0.2, 0.1, 0.08 and 0.05 *μ*m pore sizes under ultra pure nitrogen pressure.

The nanoparticles, 110 nm in diameter, have the ability to target tumors and metastasis following intravenous administration using the compromised endothelium of the tumor vasculature sprouted during neoangiogenesis; this process, known as extravasation, takes advantage of the compromised endothelium of the vasculature of the tumors generated during neoangiogenesis. Lipoplatin has shown an amazing concentration in tumors and metastases at levels up to 200-fold higher compared to the adjacent normal tissue in surgical specimens from patients \[[@B19]\].

3. Molecular Mechanisms of Cisplatin and Lipoplatin {#sec3}
===================================================

After infusion, cisplatin is rapidly excreted in the urine causing renal tubular damage. When it reaches normal and malignant cells, it uses the major copper influx transporter Ctr1 for entry inside the cytoplasm ([Figure 2](#fig2){ref-type="fig"}). Ctr1 has been convincingly demonstrated to transport cisplatin and its analogues, carboplatin, and oxaliplatin. Two copper efflux transporters, ATP7A and ATP7B, regulate the efflux of cisplatin \[[@B20]\].

The S-containing tripeptide glutathione is present in cells at mM concentrations, and the formation of complexes with cisplatin plays an important role in its detoxification and biological activities. The depletion of glutathione levels has been shown to increase the toxicity of cisplatin to kidney cells. Cancer cells that are resistant to cisplatin often have elevated glutathione levels. Glutathione could quench DNA-Pt monofunctional adducts before they can rearrange toxic bifunctional adducts on DNA. Human glutathione S-transferase P1 (GSTP1) contributes to chemoresistance and its suppression, decreasing the cisplatin-induced activation of ERK1/2 and might have synergistic therapeutic effects \[[@B21]\].

Cisplatin and other apoptotic stimuli trigger the release of cytochrome c from the mitochondrial intermembrane space to the cytosol, which induces the formation of the apoptosome and the activation of procaspase-9, leading to apoptosis. The apoptosome is an Apaf-1 cytochrome c complex that activates procaspase-9. Cisplatin can also activate the proapoptotic protein Bax, resulting in cytochrome c release, caspase activation, and apoptosis; Bax activation is implicated in the nephrotoxicity of cisplatin \[[@B22]\]. Bcl-2 plays an important role in the mitochondrial apoptotic pathway. Although the general role of Bcl-2 is antiapoptotic, Bcl-2 fragments resulting by caspase cleavage after cisplatin treatment of cells in culture could promote the apoptotic process \[[@B23]\]. Lipoplatin, releasing cisplatin molecules in the cytoplasm of the tumor cell, is also proposed to activate the mitochondrial apoptotic cascade.

During signal transduction, a cell senses both the external and internal environment and converts a stimulus into an ordered sequence of phosphorylation-dephosphorylation, protease degradation, gene regulation, or ion flux events, across the cell membrane. Receptor tyrosine kinases contribute to chemoresistance in tumors. A number of additional properties of cisplatin are now emerging including the activation of signal transduction pathways leading to apoptosis. The firing of such pathways may originate at the level of the cell membrane after damage of the receptor or lipid molecules by cisplatin, in the cytoplasm by modulation of proteins via the interaction of their thiol groups with cisplatin, (kinases, and other regulatory proteins and enzymes), or finally from DNA damage via the activation of the DNA repair pathways \[[@B24], [@B25]\].

Cisplatin induction of signaling is cell type, time and dose dependent. It induces oxidative stress and is an activator of stress-signaling pathways especially of the mitogen-activated protein (MAP) kinase cascades. The extracellular signal-regulated kinase (ERK) pathway is indeed activated by cisplatin. The acquisition of cisplatin resistance by ovarian carcinoma cells was associated with the loss of ERK activation in response to cisplatin \[[@B26]\]. ERK activation and DNA-damage induced apoptosis are tightly linked; p53 may act as one of the upstream regulators of ERK activation for the induction of apoptosis in carboplatin-treated cervical cancer cells \[[@B27]\]. The treatment of cells with high cisplatin concentrations (one order of magnitude higher than the IC~50~) induces cellular superoxide formation and caspase activation independently of nuclear DNA damage. In contrast, cisplatin concentrations at IC~50~ doses, which do not induce acute apoptosis, are sufficient for the induction of DNA damage signaling \[[@B28]\].

The PI3K/Akt cascade has an important role in the resistance of ovarian cancer cells to cisplatin, and the inhibition of PI3K/Akt increases the efficacy of cisplatin \[[@B29]\]. The Akt-specific inhibitor LY294005 increased the efficacy of docetaxel, did not affect the efficacy of 6-thioguanine, and decreased the efficacy of cisplatin, lipoplatin, oxaliplatin, and lipoxal in human colorectal adenocarcinoma sublines, suggesting a novel property of Akt in aggravating drug sensitivity \[[@B30]\].

Cisplatin appears to exhibit synergistic effects with other potent inducers of apoptosis such as a synthetic isothiocyanate; the sequential administration of both agents led to increased intracellular platinum accumulation, glutathione depletion, poly (ADP-ribosyl) polymerase cleavage, stimulation of caspase-3 activity, upregulation of p53, FasL and Gadd45alpha, cyclin B1 downregulation, and an increase in mitogen-activated protein kinases JNK, ERK, and p38 phosphorylation as well as PI3K level alterations \[[@B31]\].

4. Resistance of Tumor Cells to Cisplatin and a Role for Lipoplatin {#sec4}
===================================================================

The resistance of tumor cells to cisplatin is attributed to at least four different mechanisms: (i) decreased levels of cisplatin entrance to the cytoplasm or increased efflux through the cell membrane, (ii) increased levels of glutathione, (iii) modulation of signaling pathways, and (iv) enhanced levels of DNA repair.

However, additional pathways have been found for establishing the cisplatin resistant phenotype. For example, the selection of ovarian carcinoma cells in culture in the presence of cisplatin led to upregulated expression of the L1 adhesion molecule; this could constitute a mechanism for the establishment of chemoresistance and of a more malignant tumor phenotype \[[@B32]\].

The direct fusion of lipoplatin nanoparticles with the membrane of the tumor cell ([Figure 2](#fig2){ref-type="fig"}) suggests that lipoplatin can have applications after the failure of cisplatin front-line chemotherapy and the development of cisplatin resistance at the cell membrane level.

5. Preclinical Studies {#sec5}
======================

A comparison of the cytotoxicity of lipoplatin and cisplatin in vitro in established cell lines (derived from NSCLC, renal cell carcinoma, and in normal hematopoietic cell precursors), as well as the identification of biological markers associated with sensitivity and resistance has rendered some interesting data. ERCC1 and LRP expression levels appeared to be valid predictors of sensitivity or resistance to both drugs. A superior cytotoxicity in all tumor cell models and a much lower toxicity in normal cells for lipoplatin compared with cisplatin were found, suggesting a higher therapeutic index for the liposomal compound \[[@B33]\].

Fedier et al. \[[@B34]\] investigated whether the cytotoxic effect of lipoplatin is dependent on the functional integrity of DNA mismatch repair (MMR). MMR is a postreplicative DNA repair mechanism implicated in cell cycle control and apoptosis. MMR function was found to be a relevant determinant accounting for the cytotoxicity of lipoplatin \[[@B34]\]. A possible relationship between MMR-mediated cisplatin DNA damage signaling, and the Akt signaling pathway was also found \[[@B30]\].

The fusion between liposomes and the cell membrane was suggested based on the fusogenic properties of DPPG and lipids integrated into the shell of lipoplatin ([Figure 2](#fig2){ref-type="fig"}). Subsequent cell culture studies where the lipids of the lipoplatin nanoparticle were labelled with fluorescein isothiocyanate (FITC) established the rapid uptake and internalization of the nanoparticles ([Figure 3](#fig3){ref-type="fig"}). In these studies the fluorescent nanoparticles were incubated with MCF-7 breast cancer cells in culture for various times ranging from 5 min to 24 h, and the cells were fixed and visualized by confocal microscopy ([Figure 3](#fig3){ref-type="fig"}). Liposomes containing DPPG without cisplatin were also used as a control. The study has provided proof that the lipids of lipoplatin labelled with FITC are transferred initially (in less than 5 min) to the cell membrane of MCF-7 cells in culture and are then (from 5 min to 24 h) docked to the interior of the cell. The membrane fusion is proposed to modulate signalling, an important process for cancer cell proliferation.

The lower nephrotoxicity of lipoplatin, compared to cisplatin, was shown in mice, rats, and SCID mice \[[@B35]\], whereas animals injected with cisplatin developed renal insufficiency with clear evidence of tubular damage, but those injected with the same dose of lipoplatin were almost completely free of kidney injury \[[@B35]\].

In order to explain the lower toxicity of lipoplatin compared to cisplatin, the levels of total platinum in rat tissue after cisplatin or lipoplatin injections were determined at different time intervals. The maximum levels of total platinum after cisplatin were found in the kidney followed by the plasma, liver, lung, spleen, heart, and brain, in those tissues examined from  5 min to 5 h. At later times (up to 50 h), the order of the tissues with the highest levels of platinum was the kidney, liver spleen, plasma, lung, heart, and brain. A single treatment with 30 mg/kg lipoplatin in rats resulted in no toxicity, whereas 2 or 3 weekly administrations at 30 mg/kg in rats produced neutropenia but no nephrotoxicity. However, a single injection of 5 mg/kg cisplatin in rats resulted in severe nephrotoxicity. The levels of total platinum attained in animal kidneys after cisplatin administration are about the same as those after lipoplatin ([Figure 4](#fig4){ref-type="fig"}); however, at about 1 h and up to 5 days, the levels of total platinum are about 1 microgram after lipoplatin compared to 5 micrograms after cisplatin administration ([Figure 4](#fig4){ref-type="fig"}).

After cisplatin injection, the kidneys accumulate the highest levels of platinum among all of the animal tissues, followed by the liver and the lung. One hour after lipoplatin administration i.p., the kidney Pt levels drop from 13 to 3 *μ*g/g tissue. The highest Pt levels among all of the animal tissues are in the liver and spleen after 4 h i.p. administration maintained for over 100 h.

The treatment of dogs with lipoplatin led to the conclusion that the drug can be safely administered to clinically normal dogs at dosages of up to 150 mg/m^2^ without the need for concurrent hydration protocols. The maximum tolerated dose (MTD) of unencapsulated cisplatin in dogs has been established as 70 mg/m^2^. Therefore, lipoplatin would allow the safe and repeated administration of doses higher than the MTD of unencapsulated cisplatin \[[@B36]\].

The intrapleural administration of lipoplatin in an animal model seems to offer a more effective therapeutic index while improving tolerability. Wistar rats were treated with doses of 10 mg/kg lipoplatin (intravenously) versus 10 or 20 mg/kg lipoplatin (intrapleurally) corresponding to 60 and 120 mg/m^2^, respectively, in humans. The authors noted minor fibrotic changes in the pleura of rats injected intrapleurally, and mild kidney changes in rats injected intravenously, as expected \[[@B37]\].

6. Cellular Uptake and Cytoplasm/DNA Distribution of Cisplatin versus Lipoplatin {#sec6}
================================================================================

The antineoplastic or radio-sensitizing activity of platinum drugs is attributed to their binding to DNA. The time course of accumulation of cisplatin, lipoplatin, oxaliplatin, and lipoxal (liposomal oxaliplatin) in the human colorectal cancer HCT116 cell line and their distribution between the cytoplasm and DNA were measured by inductively coupled plasma mass spectrometry. The distribution of cytoplasm/DNA of free cisplatin and lipoplatin were similar. However, lipoxal displayed a higher accumulation in the cytoplasm compared to free oxaliplatin, consistent with its proposed mechanism of fusion with the cell membrane \[[@B38]\].

The cytotoxicity and synergic effect of platinum compounds with radiation were examined in F98 glioma cells. Lipoplatin improved the cell uptake of cisplatin by 3-fold, and its radiosensitizing potential was enhanced by 14-fold. Among the five platinum compounds tested, carboplatin and lipoplatin showed the best radiosensitizing effect. Lipoplatin seemed the most promising since it led to the best cellular incorporation and reduced all the toxicities of cisplatin \[[@B39]\].

7. Clinical Studies {#sec7}
===================

7.1. Pharmacokinetics {#sec7.1}
---------------------

In the administration of liposomal cisplatin to humans, the target was to determine the pharmacokinetics and adverse reactions. A Phase I study of 27 patients with different malignancies was performed. The drug was infused for 8 hrs every fourteen days at escalating doses. The drug levels started at 25 mg/m^2^ and were increased by 25 mg/m^2^ up to 125 mg/m^2^. Three-5 patients were selected for each dosage. Blood was taken at certain time intervals in order to estimate the total platinum plasma levels. For pharmacokinetics, blood was drawn at 0, 3, 6, 8, 12, 24 hrs and 3, 5, 7 days, into tubes containing EDTA, and total platinum levels (i.e., free plus proteins bound plus liposomal) were analyzed by atomic absorption. Total platinum was also determined in the ultrafiltrate of less plasma. The maximum level attained in the plasma was 5.7 *μ*g/mL at 8 hrs. The levels of platinum in the blood after lipoplatin infusion drop to normal on the fourth day at a dose of 100 mg/m^2^, but at a dose of 125 mg/m^2^ platinum can be detected in the blood for 7 days ([Table 1](#tab1){ref-type="table"}) \[[@B40]\]. Renal function tests (blood urea, serum creatinine, and creatinine clearance) showed no change before and after treatment. The excretion of platinum in the urine in lipoplatin-treated patients attains a maximum within 8 hrs (infusion period) and declines thereafter. During the 3 following days (after infusion) 40.7% of the total platinum was excreted in the urine. Toxicity was very mild (grade 1 or 2 neutropenia and nausea/vomiting) at the 125 mg/m^2^ dosage level. In another trial, the tumor uptake of lipoplatin was examined in comparison to normal tissue, in 4 patients with hepatocellular adenocarcinoma, gastric cancer, and colon cancer. Lipoplatin was administered to the patients 24 hours before the surgery \[[@B19]\]. This study showed liposomal cisplatin accumulation in tumors as compared to normal tissue after the intravenous infusion of lipoplatin. Among the various surgical specimens examined, gastric tumors revealed the highest levels of total platinum (up to 262 *μ*g cisplatin/gr tissue). The liver metastatic specimen displayed a total amount of 131.15 *μ*g platinum/gr of tissue compared to 20.94 *μ*g platinum/gr of normal liver tissue. Both specimens of gastric tumors appeared to accumulate the highest amounts of platinum among all specimens analyzed in this study: 262.62 and 66.38 *μ*g/gr of tissue. The total platinum levels in the colon tumor specimens were 11.26 and 7.69 *μ*g platinum/gr of tissue compared to 0.06 *μ*g/gr normal colon tissue \[[@B19]\].

7.2. Dose-Limited Toxicity and Maximum Tolerated Doses {#sec7.2}
------------------------------------------------------

The human testing of this new agent primarily required the definition of toxicity by investigating the MTD as well as the dose-limited toxicity (DLT). Two Phase I and I-II studies examined these objectives. The first trial was in patients with advanced pancreatic cancer. The results showed that the dosages which began to produce side effects were 100 mg/m^2^ and 125 mg/m^2^. But these dosages did not later prove that this was the DLT since lipoplatin was combined with gemcitabine, the latter which may have been responsible for the toxicity \[[@B41]\]. The second study defined similar doses as the DLT and MTD. This trial also used two agents, lipoplatin and gemcitabine in pretreated patients with NSCLC. The two drugs were repeated on day 8. The small number of 13 patients was not efficacious enough to determine ample data concerning toxicity \[[@B42]\]. In both these aforementioned studies, there was also a defect in that all of the patients had undergone chemotherapy pretreatment when they were recruited and the efficacy of lipoplatin was tested. A proper third Phase I trial was eventually performed. The main objective of this study was to determine the DLT and MTD of lipoplatin tested as a single agent and in combination with a second cytotoxic agent. The selected second agent was paclitaxel. All of the patients had NSCLC. Adverse reactions, mainly myelotoxicity, renal toxicity and gastrointestinal toxicity (nausea, vomiting, diarrhea) were determined. Sixty-six patients were recruited and evaluated. Thirty-nine patients comprised the group that received lipoplatin monotherapy, and 27 patients were given lipoplatin in combination with paclitaxel. In the first group, the dosage of lipoplatin started at the level of 125 mg/m^2^ and the drug-dose escalation increased to 350 mg/m^2^. It was determined that 350 mg/m^2^ was the DLT and 300 mg/m^2^ the MDT. In the group that received combination therapy, the escalation of paclitaxel started at 100 mg/m^2^ and went up to 175 mg/m^2^ and of lipoplatin from 100 mg/m^2^ to 250 mg/m^2^. The results of the combined treatment evaluation determined the DLT as 250 mg/m^2^ and the MTD, 200 mg/m^2^. Nausea, vomiting, fatigue, and neutropenia were not higher than grade 1-2, and other adverse reactions in a small percentage of patients reached grade 3. In the combined modality, other side effects, such as neurotoxicity, were observed, and this was attributed to paclitaxel. Grade 1 nephrotoxicity was observed in a small percentage of patients, but this was only temporary ([Table 2](#tab2){ref-type="table"}) \[[@B43]\].

Over the last five years, several Phase II and III trials have been performed in different institutions and countries. Lipoplatin has been tested in the following malignancies: pancreatic cancer, head and neck cancer, mesothelioma, breast and gastric cancer, and NSCLC. In pancreatic cancer, lipoplatin was administered as second-line treatment in combination with gemcitabine. The patients had initially undergone gemcitabine monotherapy as first-line treatment and were experiencing disease progression. The combination of lipoplatin with gemcitabine rendered a response rate of 8% \[[@B41]\].

A trial was done concerning a combination of lipoplatin 120 mg/m^2^ plus 5-fluorouracil 400 mg/m^2^ and leucovorin, both cytotoxic drugs administered weekly along with radiotherapy. The cytotoxic agents were given on day 1 and radiotherapy (dosage 3.5 Gy × 3, days 2, 3, 4) for four or five weeks. This treatment was given to patients with advanced gastric cancer. No serious toxicity was observed, and the therapy was well tolerated; 18.2% patients developed grade 1 renal toxicity and nausea and 25% showed fatigue. A good response to the combined treatment was observed \[[@B44]\].

It is too early to confirm that lipoplatin is effective in mesothelioma. There is a case report indicating the responsiveness of mesothelioma to lipoplatin given in combination with gemcitabine as second-line treatment on disease recurrence \[[@B45]\].

The testing of the toxicity and effectiveness of liposomal cisplatin was done in patients with squamous cell carcinoma of the head and neck. This was a randomized study comparing lipoplatin combined with 5-fluorouracil versus cisplatin combined with 5-fluorouracil. The toxicity was well tolerated. Grade 3 renal toxicity was much lower after lipoplatin administration than after cisplatin. Higher myelotoxicity was observed in the cisplatin arm (31.7% versus 12% in the lipoplatin arm). Mucositis and peripheral neuropathy were also much higher in the cisplatin group. The response rate was higher in the cisplatin arm, but stable disease was higher in the lipoplatin arm. This low responsiveness of the lipoplatin arm may be due to the quite low dosage administered and its short duration. One should take into account that the MTD is 200 mg/m^2^ and not 100 mg/m^2^ \[[@B46]\].

A Phase II trial combining lipoplatin with vinorelbine in first-line treatment of HER2/neu-negative metastatic breast cancer was done. The investigators administered the above agents on the basis of the rationale that the frequent use of anthracyclines and taxanes in the adjuvant setting of breast cancer has led to drug resistance and cardiac toxicity. This raised the need for new agents in the metastatic setting. Another reason for testing the aforementioned combination was that the use of cisplatin-vinorelbine showed interesting results with an overall response rate of 64%. The administered dose of lipoplatin was 120 mg/m^2^ and of vinorelbine 30 mg/m^2^. The objective response rate of the latter combination was 50% (one complete response). Stable disease was 45.5%. Toxicity was well tolerated \[[@B47]\].

One Phase II and two Phase III trials have been recently integrated and published. In these studies, lipoplatin was combined with a second agent in comparison with cisplatin also combined with the same second agent, and the objectives were to determine the side effects and efficacy. In the Phase II randomized study, lipoplatin (dosage 120 mg/m^2^ given on days 1, 8, 15) combined with gemcitabine (1000 mg/m^2^ given on days 1, 8) was compared with cisplatin (100 mg/m^2^ day 1) combined with gemcitabine (1000 mg/m^2^ given on days 1, 8). With respect to efficacy, the overall response rate of the lipoplatin arm was 31.7%, and the cisplatin arm 25.6%. Although the efficacy of lipoplatin was not statistically higher than that of cisplatin, a better response rate was achieved with lipoplatin, particularly in cases of adenocarcinoma. The more important finding was the toxicity outcome which was shown to be much lower in patients treated with lipoplatin versus in patients treated with cisplatin. Very low nephrotoxicity was observed in the patients who received lipoplatin. Although the aforementioned study \[[@B48]\] included a rather limited number of patients (88 in total), the results were confirmed by another study which was done in parallel to the above trial.

These results with respect to the study done in parallel, mentioned above, are as follows: this Phase III trial included 229 evaluable patients. The differences between this study and the previous one were, the number of patients, the dosage of the drugs, the repetition of the courses, and the second agent which was combined with lipoplatin and cisplatin. The dose of lipoplatin was 200 mg/m^2^, which is the proper MTD combined with paclitaxel 135 mg/m^2^ repeated every 2 weeks for a planned 9 courses. The control arm received cisplatin 75 mg/m^2^ also combined with paclitaxel 135 mg/m^2^, repeated every 2 weeks. The planned number of courses was 9. The treatment of both agents and arms was on day 1. The main objectives of this trial were to determine the toxicity and median survival. The results were quite impressive; nephrotoxicity, in particular, leukopenia, nausea/vomiting, and asthenia were statistically significantly lower after lipoplatin treatment (*P* ≤ 0.001, 0.017, 0.042, 0.019, resp.) ([Table 3](#tab3){ref-type="table"}). The comparison of efficacy was also important; the response rate was 59.7% for the lipoplatin arm, and 47% for the cisplatin arm (no statistically significant difference, *P*  =  0.073) ([Table 4](#tab4){ref-type="table"}). The median and overall survival for both arms was the same \[[@B49]\].

The data documented in the last two trials indicate that the cisplatin formulation (lipoplatin) could be considered as the best substitute for cisplatin, at least in NSCLC, with regard to efficacy and toxicity.

The next Phase III trial was based on certain indications from the previous trials, and this was the possibility that NSCLC subtypes may have a different response rate with the administration of lipoplatin or cisplatin. This study recruited patients with nonsquamous cell lung cancer, mainly adenocarcinomas, and they were treated with lipoplatin combined with paclitaxel versus cisplatin combined with paclitaxel. The dosage and administration of these two combined treatments was the same as in the previous study. It was found in 202 patients randomized into two groups, that the response rate was superior in the lipoplatin group. The difference was statistically significant (*P* = 0.036) ([Table 5](#tab5){ref-type="table"}). The median survival for the lipoplatin group was 10 months and for cisplatin group 8 months, approaching statistical significance (*P* = 0.1551) \[[@B50]\].

There are data examining the possibility of using lipoplatin in cancer patients with renal failure. The preliminary data show that patients with serum creatinine ranging from 1.6--3.5 mg/dL tolerate lipoplatin without increasing renal failure and without side effects such as neutropenia, nausea/vomiting, and fatigue.

8. Conclusion {#sec8}
=============

The efforts over the last 20 years to produce a substitute for cisplatin, a very important and effective anticancer agent, with a similarly effective and less toxic agent, have not properly succeeded. The current data in a number of preclinical and clinical trials shed new light on the previous efforts to produce a substitute for cisplatin. Liposomal cisplatin (lipoplatin), is a new formulation of cisplatin and one would expect at least to achieve equal effectiveness. Phase I, II, and III trials have shown lipoplatin to produce similar efficacy to that of cisplatin in pancreatic, head and neck, breast cancers, and NSCLC (the latter has been more broadly tested). In a new substitute for cisplatin, what is more important, apart from effectiveness, is significant toxicity reduction. The reduction of toxicity, mainly nephrotoxicity, has been shown and confirmed in published trials. It will be important to use this new cisplatin formulation in future trials and to test it in malignancies such as ovarian and bladder cancers.

![Depiction of a lipoplatin nanoparticle (b). Cisplatin molecules are depicted as blue spheres surrounded by the lipid bilayer with the PEGylated lipid sticking out like hair from the outer surface. Thus, this toxic substance, cisplatin, is camouflaged by its lipid shell as a nutrient. This nanoparticle can pass undetected by macrophages after intravenous injection to human cancer patients because of its PEG coating thus escaping immune surveillance \[[@B51]\]. © CNRS Photothèque/SAGASCIENCE/CAILLAUD François.](JDD2012-581363.001){#fig1}

![Penetration of lipoplatin nanoparticles through the cell membrane of tumor cells. lipoplatin nanoparticles once inside the tumor cell mass can fuse with the cell membrane because of the presence of the fusogenic lipid DPPG in their lipid bilayer; an alternative mechanism proposed is that lipoplatin is taken by *endocytosis* by tumor cells as shown from lipoplatin containing fluorescent lipids and imaging of the tumor cells in culture thus treated with fluorescent microscopy (see [Figure 3](#fig3){ref-type="fig"}). These processes occurring at the cell membrane level are promoted by the lipid shell of the nanoparticles (disguised as nutrients) \[[@B51]\].](JDD2012-581363.002){#fig2}

![Lipoplatin or DPPG-liposomes with fluorescent lipids enter rapidly MCF-7 breast cancer cells in culture. Time-course processing of FITC-labeled DPPG-containing liposomes (a) and Lipoplatin (b) using confocal microscopy. At 5 min, the majority of the signal is localized in the membrane. Lipids are rapidly internalized and at 4--24 hours, a strong signal is observed in the cytoplasm and at the perinuclear area. These results demonstrate that *lipoplatin or DPPG-liposomes* nanoparticles are able to cross the cell membrane barrier \[[@B51]\].](JDD2012-581363.003){#fig3}

![Kidney and other tissue accumulation of total platinum after *cisplatin* injection of rats (0--5h) \[[@B51]\].](JDD2012-581363.004){#fig4}

######

Pharmacokinetic parameters of total platinum in patients\' sera at the different dose levels.

  Dose   Pts   AUC~0*∅*A~   *C* ~max ~    Cl     *K* ~el~   *t* ~1/2~   *V* ~*ss*~
  ------ ----- ------------ ------------- ------ ---------- ----------- ------------
  25     5     139.63       2.48 ± 1.18   0.18   0.0114     60.79       15.71
  50     3     119.19       2.87 ± 0.59   0.42   0.0001     N/A         N/A
  100    5     172.89       3.74 ± 1.18   0.58   0.0059     117.46      98.03
  125    4     256.09       5.65 ± 2.67   0.49   0.0085     81.53       57.42

N/A, not applicable.

######

Toxicity: lipoplatin monotherapy.

  Dosage lipoplatin mg/m^2^   Toxicity          Grade
  --------------------------- ----------------- ------- ----- ----- -----
  150--250                    Nausea-vomiting   ---     ---   ---   ---
  Fatigue                     ---               ---     ---   ---
  Diarrhea                    ---               ---     ---   ---
  Nephrotoxicity              ---               ---     ---   ---
  Neutropenia                 ---               ---     ---   ---
  Neurotoxicity               ---               ---     ---   ---

  300                         Nausea-vomiting   2/4     1/4   ---   ---
  Fatigue                     2/4               1/4     ---   ---
  Neutropenia                 1/4               ---     ---   ---
  Nephrotoxicity              1/4               ---     ---   ---

  350                         Nausea-vomiting   1/4     3/4   ---   ---
  Fatigue                     1/4               3/4     ---   ---
  Neutropenia                 2/4               1/4     1/4   ---
  Nephrotoxicity              2/4               1/4     1/4   ---

######

Toxicity/statistical differences.

  Toxicity grade 1--4        Arm A       Arm B
  -------------------------- ----------- ----------- ----------
  Anemia                     50 (43.9)   62 (54.9)   0.112
  Leucopenia (neutropenia)   38 (33.3)   52 (45.2)   0.017
  Thrombocytopenia           2 (1.8)     3 (2.6)     1.000^†^
  Nephrotoxicity (renal)     7 (6.1)     46 (40.0)   \<0.001
  Neurotoxicity              52 (45.6)   63 (54.8)   0.145
  GI toxic nausea/vomiting   37 (32.5)   52 (45.2)   0.042
  GI diarrhea                2 (1.8)     3 (2.6)     1.000^†^
  Asthenia                   65 (57.0)   82 (71.3)   0.019
  Alopecia                   96 (84.2)   87 (75.7)   0.134

GI, gastrointestinal.

\*Pearson\'s chi-square test.

^†^Fisher\'s exact test.

######

Response rate/survival time (months), Log-rank test *P* value: 0.577.

                        ARM
  --------------- ----- -------- ----------- ------ -------
  CR
    *n*                 1        0           1      ---
   % within ARM         0.9      0.0         0.4    ---
  PR
    *n*                 67       54          121
   % within ARM         58.8     47.0        52.8   0.073
  SD
    *n*                 42       50          92
   % within ARM         36.8     43.5        40.2   0.306
  PD
    *n*                 4        11          15
   % within ARM         3.5      9.6         6.6    0.064

  Total           *n*   114      115         229

  Survival time   *n*   Median   95% CI

  Arm A           114   9.0      6.2--11.8
  Arm B           115   10.0     6.8--13.2

  Total sample    229   10.0     8.3--11.7

CR: complete response; PR: partial response; SD: stable disease; PD: progressive disease.

\*Pearson\'s chi-square test.

######

Response rate.

                        Arm A         Arm B         *P* value
  --------------------- ------------- ------------- -----------
  Partial response      61 (59.22%)   42 (42.42%)   0.036
  Stable disease        35 (33.98%)   43 (43.43%)   0.220
  Progressive disease   7 (6.80%)     14 (14.14%)   0.110

[^1]: Academic Editor: Rassoul Dinarvand


Effect of intracoronary injections of sonicated microbubbles on left ventricular contractility.
Despite the recent interest in contrast-enhanced echocardiography as a means of defining myocardial perfusion, the effects of echo contrast agents on left ventricular (LV) contractility in humans remains poorly defined. This is particularly relevant because intracoronary injection of contrast agents used for angiographic visualization of coronary arteries produces significant alterations in LV hemodynamics. The relation of LV end-systolic wall stress (sigma es) to rate-corrected velocity of fiber shortening (Vcfc), a load-independent index of contractility, was studied in 7 patients undergoing elective coronary arteriography. Two-dimensional and targeted M-mode echocardiographic and central aortic pressure tracings were recorded during injections of standard volumes of angiographic (7 to 9 ml of nonsonicated Renografin-76) and echocardiographic (1.5 to 2.0 ml of sonicated Renografin-76) contrast agents into the left main coronary artery. The order in which agents were injected was randomly determined. Myocardial contractility was assessed under control conditions and 5 and 15 seconds after injection. Alterations in contractility relative to control were measured as the change in Vcfc after elimination of afterload (sigma es) as a confounding variable. An injection of Renografin-76 adequate for angiographic imaging of coronary artery anatomy resulted in a significant depression of LV contractility (p less than 0.001) in conjunction with a tendency toward increased afterload (p = 0.12); recovery occurred by 15 seconds after injection. The smaller amounts of sonicated Renografin-76 required to give adequate contrast enhancement of the myocardium did not alter LV contractile state or afterload.(ABSTRACT TRUNCATED AT 250 WORDS)


Drinking water quality assessment.
Drinking water quality is the great public health concern because it is a major risk factor for high incidence of diarrheal diseases in Nepal. In the recent years, the prevalence rate of diarrhoea has been found the highest in Myagdi district. This study was carried out to assess the quality of drinking water from different natural sources, reservoirs and collection taps at Arthunge VDC of Myagdi district. A cross-sectional study was carried out using random sampling method in Arthunge VDC of Myagdi district from January to June,2010. 84 water samples representing natural sources, reservoirs and collection taps from the study area were collected. The physico-chemical and microbiological analysis was performed following standards technique set by APHA 1998 and statistical analysis was carried out using SPSS 11.5. The result was also compared with national and WHO guidelines. Out of 84 water samples (from natural source, reservoirs and tap water) analyzed, drinking water quality parameters (except arsenic and total coliform) of all water samples was found to be within the WHO standards and national standards.15.48% of water samples showed pH (13) higher than the WHO permissible guideline values. Similarly, 85.71% of water samples showed higher Arsenic value (72) than WHO value. Further, the statistical analysis showed no significant difference (P<0.05) of physico-chemical parameters and total coliform count of drinking water for collection taps water samples of winter (January, 2010) and summer (June, 2010). The microbiological examination of water samples revealed the presence of total coliform in 86.90% of water samples. The results obtained from physico-chemical analysis of water samples were within national standard and WHO standards except arsenic. The study also found the coliform contamination to be the key problem with drinking water.


Exploration of the conformational space of myosin recovery stroke via molecular dynamics.
Muscle contractions are driven by cyclic conformational changes of myosin, whose molecular mechanisms of operation are being elucidated by recent advances in crystallographic studies and single molecule experiments. To complement such structural studies and consider the energetics of the conformational changes of myosin head, umbrella sampling molecular dynamics (MD) simulations were performed with the all-atom model of the scallop myosin sub-fragment 1 (S1) with a bound ATP in solution in explicit water using the crystallographic near-rigor and transition state conformations as two references. The constraints on RMSD reaction coordinates used for the umbrella sampling were found to steer the conformational changes efficiently, and relatively close correlations have been observed between the set of characteristic structural changes including the lever arm rotation and the closing of the nucleotide binding pocket. The lever arm angle and key residue interaction distances in the nucleotide binding pocket and the relay helix show gradual changes along the recovery stroke reaction coordinate, consistent with previous crystallographic and computational minimum energy studies. Thermal fluctuations, however, appear to make the switch-2 coordination of ATP more flexible than suggested by crystal structures. The local solvation environment of the fluorescence probe, Trp 507 (scallop numbering), also appears highly mobile in the presence of thermal fluctuations.


Q:

Showing that if the conditional probabilities exist.

I'm trying to show that
If the conditional probabilities exist, then
 P(A1 $\cap$ A2 $\cap$ ... $\cap$An) = P(A1)P(A2|A1)...P(An|A1$\cap$A2$\cap$...$\cap$An-1).
I'm unsure how to approach these sorts of problems as I'm still fairly new to Probability.
I started off with saying:
Let A1, A2, ..., An be events, each with P(Ai) >= 0 for all i $\in$ {1, 2, 3, ...}.
We have by our hypothesis that the conditional probabilities exist, so by definition we have that:
P(A2|A1) = $\frac{P(A2 \cap A1)}{P(A1)}$
...
P(An|An-1) = $\frac{P(An \cap An-1)}{P(An-1)}$
Then by the multiplication law:
P(An-1 $\cap$ An) = P(An|An-1)P(An-1)
(and so on).
So
P(A1 $\cap$ A2 $\cap$ ... $\cap$An) = P(A1 $\cap$ A2) P(A3 $\cap$ A4) ... P(An-1$\cap$An)
Before I even go on, is what I did here correct so far? The above line strikes me as not convincing as I'm not sure if there is such a property to allow me to do what I did above. The idea I had was to substitute an n number of conditional probability equations (in the form of the multiplicative law) and then multiply them all together.
But generally speaking I am not sure if I understand how to approach these sorts of problems - so any help appreciated.
Do note that this is elementary probability so I only have a limited tool set I can use.

A:

note that the k'th term is
$$P(A_k| A_1\cap A_2\cap ...\cap A_{k-1} ) = \frac{P( A_1\cap A_2\cap ...\cap A_{k-1}\cap A_k )}{ P(A_1\cap A_2\cap ...\cap A_{k-1} )}$$
from which you obtain a telescopic product


//
//  Copyright (c) 2000-2002
//  Joerg Walter, Mathias Koch
//
//  Permission to use, copy, modify, distribute and sell this software
//  and its documentation for any purpose is hereby granted without fee,
//  provided that the above copyright notice appear in all copies and
//  that both that copyright notice and this permission notice appear
//  in supporting documentation.  The authors make no representations
//  about the suitability of this software for any purpose.
//  It is provided "as is" without express or implied warranty.
//
//  The authors gratefully acknowledge the support of
//  GeNeSys mbH & Co. KG in producing this work.
//

#ifndef _BOOST_UBLAS_VECTOR_PROXY_
#define _BOOST_UBLAS_VECTOR_PROXY_

#include <boost/numeric/ublas/vector_expression.hpp>
#include <boost/numeric/ublas/detail/vector_assign.hpp>
#include <boost/numeric/ublas/detail/temporary.hpp>

// Iterators based on ideas of Jeremy Siek

namespace boost { namespace numeric { namespace ublas {

    // Vector based range class
    template<class V>
    class vector_range:
        public vector_expression<vector_range<V> > {

        typedef vector_range<V> self_type;
    public:
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
        using vector_expression<self_type>::operator ();
#endif
        typedef const V const_vector_type;
        typedef V vector_type;
        typedef typename V::size_type size_type;
        typedef typename V::difference_type difference_type;
        typedef typename V::value_type value_type;
        typedef typename V::const_reference const_reference;
        typedef typename boost::mpl::if_<boost::is_const<V>,
                                          typename V::const_reference,
                                          typename V::reference>::type reference;
        typedef typename boost::mpl::if_<boost::is_const<V>,
                                          typename V::const_closure_type,
                                          typename V::closure_type>::type vector_closure_type;
        typedef basic_range<size_type, difference_type> range_type;
        typedef const self_type const_closure_type;
        typedef self_type closure_type;
        typedef typename storage_restrict_traits<typename V::storage_category,
                                                 dense_proxy_tag>::storage_category storage_category;

        // Construction and destruction
        BOOST_UBLAS_INLINE
        vector_range (vector_type &data, const range_type &r):
            data_ (data), r_ (r.preprocess (data.size ())) {
            // Early checking of preconditions here.
            // BOOST_UBLAS_CHECK (r_.start () <= data_.size () &&
            //                   r_.start () + r_.size () <= data_.size (), bad_index ());
        }
        BOOST_UBLAS_INLINE
        vector_range (const vector_closure_type &data, const range_type &r, bool):
            data_ (data), r_ (r.preprocess (data.size ())) {
            // Early checking of preconditions here.
            // BOOST_UBLAS_CHECK (r_.start () <= data_.size () &&
            //                    r_.start () + r_.size () <= data_.size (), bad_index ());
        }

        // Accessors
        BOOST_UBLAS_INLINE
        size_type start () const {
            return r_.start ();
        }
        BOOST_UBLAS_INLINE
        size_type size () const {
            return r_.size ();
        }

        // Storage accessors
        BOOST_UBLAS_INLINE
        const vector_closure_type &data () const {
            return data_;
        }
        BOOST_UBLAS_INLINE
        vector_closure_type &data () {
            return data_;
        }

        // Element access
#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
        BOOST_UBLAS_INLINE
        const_reference operator () (size_type i) const {
            return data_ (r_ (i));
        }
        BOOST_UBLAS_INLINE
        reference operator () (size_type i) {
            return data_ (r_ (i));
        }

        BOOST_UBLAS_INLINE
        const_reference operator [] (size_type i) const {
            return (*this) (i);
        }
        BOOST_UBLAS_INLINE
        reference operator [] (size_type i) {
            return (*this) (i);
        }
#else
        BOOST_UBLAS_INLINE
        reference operator () (size_type i) const {
            return data_ (r_ (i));
        }

        BOOST_UBLAS_INLINE
        reference operator [] (size_type i) const {
            return (*this) (i);
        }
#endif

        // ISSUE can this be done in free project function?
        // Although a const function can create a non-const proxy to a non-const object
        // Critical is that vector_type and data_ (vector_closure_type) are const correct
        BOOST_UBLAS_INLINE
        vector_range<vector_type> project (const range_type &r) const {
            return vector_range<vector_type> (data_, r_.compose (r.preprocess (data_.size ())), false);
        }

        // Assignment
        BOOST_UBLAS_INLINE
        vector_range &operator = (const vector_range &vr) {
            // ISSUE need a temporary, proxy can be overlaping alias
            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vr));
            return *this;
        }
        BOOST_UBLAS_INLINE
        vector_range &assign_temporary (vector_range &vr) {
            // assign elements, proxied container remains the same
            vector_assign<scalar_assign> (*this, vr);
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_range &operator = (const vector_expression<AE> &ae) {
            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_range &assign (const vector_expression<AE> &ae) {
            vector_assign<scalar_assign> (*this, ae);
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_range &operator += (const vector_expression<AE> &ae) {
            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_range &plus_assign (const vector_expression<AE> &ae) {
            vector_assign<scalar_plus_assign> (*this, ae);
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_range &operator -= (const vector_expression<AE> &ae) {
            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_range &minus_assign (const vector_expression<AE> &ae) {
            vector_assign<scalar_minus_assign> (*this, ae);
            return *this;
        }
        template<class AT>
        BOOST_UBLAS_INLINE
        vector_range &operator *= (const AT &at) {
            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
            return *this;
        }
        template<class AT>
        BOOST_UBLAS_INLINE
        vector_range &operator /= (const AT &at) {
            vector_assign_scalar<scalar_divides_assign> (*this, at);
            return *this;
        }

        // Closure comparison
        BOOST_UBLAS_INLINE
        bool same_closure (const vector_range &vr) const {
            return (*this).data_.same_closure (vr.data_);
        }

        // Comparison
        BOOST_UBLAS_INLINE
        bool operator == (const vector_range &vr) const {
            return (*this).data_ == vr.data_ && r_ == vr.r_;
        }

        // Swapping
        BOOST_UBLAS_INLINE
        void swap (vector_range vr) {
            if (this != &vr) {
                BOOST_UBLAS_CHECK (size () == vr.size (), bad_size ());
                // Sparse ranges may be nonconformant now.
                // std::swap_ranges (begin (), end (), vr.begin ());
                vector_swap<scalar_swap> (*this, vr);
            }
        }
        BOOST_UBLAS_INLINE
        friend void swap (vector_range vr1, vector_range vr2) {
            vr1.swap (vr2);
        }

        // Iterator types
    private:
        typedef typename V::const_iterator const_subiterator_type;
        typedef typename boost::mpl::if_<boost::is_const<V>,
                                          typename V::const_iterator,
                                          typename V::iterator>::type subiterator_type;

    public:
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
        typedef indexed_iterator<vector_range<vector_type>,
                                 typename subiterator_type::iterator_category> iterator;
        typedef indexed_const_iterator<vector_range<vector_type>,
                                       typename const_subiterator_type::iterator_category> const_iterator;
#else
        class const_iterator;
        class iterator;
#endif

        // Element lookup
        BOOST_UBLAS_INLINE
        const_iterator find (size_type i) const {
            const_subiterator_type it (data_.find (start () + i));
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
            return const_iterator (*this, it.index ());
#else
            return const_iterator (*this, it);
#endif
        }
        BOOST_UBLAS_INLINE
        iterator find (size_type i) {
            subiterator_type it (data_.find (start () + i));
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
            return iterator (*this, it.index ());
#else
            return iterator (*this, it);
#endif
        }

#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
        class const_iterator:
            public container_const_reference<vector_range>,
            public iterator_base_traits<typename const_subiterator_type::iterator_category>::template
                        iterator_base<const_iterator, value_type>::type {
        public:
            typedef typename const_subiterator_type::difference_type difference_type;
            typedef typename const_subiterator_type::value_type value_type;
            typedef typename const_subiterator_type::reference reference;
            typedef typename const_subiterator_type::pointer pointer;

            // Construction and destruction
            BOOST_UBLAS_INLINE
            const_iterator ():
                container_const_reference<self_type> (), it_ () {}
            BOOST_UBLAS_INLINE
            const_iterator (const self_type &vr, const const_subiterator_type &it):
                container_const_reference<self_type> (vr), it_ (it) {}
            BOOST_UBLAS_INLINE
            const_iterator (const iterator &it):
                container_const_reference<self_type> (it ()), it_ (it.it_) {}

            // Arithmetic
            BOOST_UBLAS_INLINE
            const_iterator &operator ++ () {
                ++ it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator -- () {
                -- it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator += (difference_type n) {
                it_ += n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator -= (difference_type n) {
                it_ -= n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            difference_type operator - (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ - it.it_;
            }

            // Dereference
            BOOST_UBLAS_INLINE
            const_reference operator * () const {
                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
                return *it_;
            }

            // Index
            BOOST_UBLAS_INLINE
            size_type index () const {
                return it_.index () - (*this) ().start ();
            }

            // Assignment
            BOOST_UBLAS_INLINE
            const_iterator &operator = (const const_iterator &it) {
                container_const_reference<self_type>::assign (&it ());
                it_ = it.it_;
                return *this;
            }

            // Comparison
            BOOST_UBLAS_INLINE
            bool operator == (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ == it.it_;
            }
            BOOST_UBLAS_INLINE
            bool operator < (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ < it.it_;
            }

        private:
            const_subiterator_type it_;
        };
#endif

        BOOST_UBLAS_INLINE
        const_iterator begin () const {
            return find (0);
        }
        BOOST_UBLAS_INLINE
        const_iterator end () const {
            return find (size ());
        }

#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
        class iterator:
            public container_reference<vector_range>,
            public iterator_base_traits<typename subiterator_type::iterator_category>::template
                        iterator_base<iterator, value_type>::type {
        public:
            typedef typename subiterator_type::difference_type difference_type;
            typedef typename subiterator_type::value_type value_type;
            typedef typename subiterator_type::reference reference;
            typedef typename subiterator_type::pointer pointer;

            // Construction and destruction
            BOOST_UBLAS_INLINE
            iterator ():
                container_reference<self_type> (), it_ () {}
            BOOST_UBLAS_INLINE
            iterator (self_type &vr, const subiterator_type &it):
                container_reference<self_type> (vr), it_ (it) {}

            // Arithmetic
            BOOST_UBLAS_INLINE
            iterator &operator ++ () {
                ++ it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            iterator &operator -- () {
                -- it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            iterator &operator += (difference_type n) {
                it_ += n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            iterator &operator -= (difference_type n) {
                it_ -= n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            difference_type operator - (const iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ - it.it_;
            }

            // Dereference
            BOOST_UBLAS_INLINE
            reference operator * () const {
                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
                return *it_;
            }

            // Index
            BOOST_UBLAS_INLINE
            size_type index () const {
                return it_.index () - (*this) ().start ();
            }

            // Assignment
            BOOST_UBLAS_INLINE
            iterator &operator = (const iterator &it) {
                container_reference<self_type>::assign (&it ());
                it_ = it.it_;
                return *this;
            }

            // Comparison
            BOOST_UBLAS_INLINE
            bool operator == (const iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ == it.it_;
            }
            BOOST_UBLAS_INLINE
            bool operator < (const iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ < it.it_;
            }

        private:
            subiterator_type it_;

            friend class const_iterator;
        };
#endif

        BOOST_UBLAS_INLINE
        iterator begin () {
            return find (0);
        }
        BOOST_UBLAS_INLINE
        iterator end () {
            return find (size ());
        }

        // Reverse iterator
        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
        typedef reverse_iterator_base<iterator> reverse_iterator;

        BOOST_UBLAS_INLINE
        const_reverse_iterator rbegin () const {
            return const_reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator rend () const {
            return const_reverse_iterator (begin ());
        }
        BOOST_UBLAS_INLINE
        reverse_iterator rbegin () {
            return reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        reverse_iterator rend () {
            return reverse_iterator (begin ());
        }

    private:
        vector_closure_type data_;
        range_type r_;
    };

    // Simple Projections
    template<class V>
    BOOST_UBLAS_INLINE
    vector_range<V> subrange (V &data, typename V::size_type start, typename V::size_type stop) {
        typedef basic_range<typename V::size_type, typename V::difference_type> range_type;
        return vector_range<V> (data, range_type (start, stop));
    }
    template<class V>
    BOOST_UBLAS_INLINE
    vector_range<const V> subrange (const V &data, typename V::size_type start, typename V::size_type stop) {
        typedef basic_range<typename V::size_type, typename V::difference_type> range_type;
        return vector_range<const V> (data, range_type (start, stop));
    }

    // Generic Projections
    template<class V>
    BOOST_UBLAS_INLINE
    vector_range<V> project (V &data, typename vector_range<V>::range_type const &r) {
        return vector_range<V> (data, r);
    }
    template<class V>
    BOOST_UBLAS_INLINE
    const vector_range<const V> project (const V &data, typename vector_range<V>::range_type const &r) {
        // ISSUE was: return vector_range<V> (const_cast<V &> (data), r);
        return vector_range<const V> (data, r);
    }
    template<class V>
    BOOST_UBLAS_INLINE
    vector_range<V> project (vector_range<V> &data, const typename vector_range<V>::range_type &r) {
        return data.project (r);
    }
    template<class V>
    BOOST_UBLAS_INLINE
    const vector_range<V> project (const vector_range<V> &data, const typename vector_range<V>::range_type &r) {
        return data.project (r);
    }

    // Specialization of temporary_traits
    template <class V>
    struct vector_temporary_traits< vector_range<V> >
    : vector_temporary_traits< V > {} ;

    // Vector based slice class
    template<class V>
    class vector_slice:
        public vector_expression<vector_slice<V> > {

        typedef vector_slice<V> self_type;
    public:
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
        using vector_expression<self_type>::operator ();
#endif
        typedef const V const_vector_type;
        typedef V vector_type;
        typedef typename V::size_type size_type;
        typedef typename V::difference_type difference_type;
        typedef typename V::value_type value_type;
        typedef typename V::const_reference const_reference;
        typedef typename boost::mpl::if_<boost::is_const<V>,
                                          typename V::const_reference,
                                          typename V::reference>::type reference;
        typedef typename boost::mpl::if_<boost::is_const<V>,
                                          typename V::const_closure_type,
                                          typename V::closure_type>::type vector_closure_type;
        typedef basic_range<size_type, difference_type> range_type;
        typedef basic_slice<size_type, difference_type> slice_type;
        typedef const self_type const_closure_type;
        typedef self_type closure_type;
        typedef typename storage_restrict_traits<typename V::storage_category,
                                                 dense_proxy_tag>::storage_category storage_category;

        // Construction and destruction
        BOOST_UBLAS_INLINE
        vector_slice (vector_type &data, const slice_type &s):
            data_ (data), s_ (s.preprocess (data.size ())) {
            // Early checking of preconditions here.
            // BOOST_UBLAS_CHECK (s_.start () <= data_.size () &&
            //                    s_.start () + s_.stride () * (s_.size () - (s_.size () > 0)) <= data_.size (), bad_index ());
        }
        BOOST_UBLAS_INLINE
        vector_slice (const vector_closure_type &data, const slice_type &s, int):
            data_ (data), s_ (s.preprocess (data.size ())) {
            // Early checking of preconditions here.
            // BOOST_UBLAS_CHECK (s_.start () <= data_.size () &&
            //                    s_.start () + s_.stride () * (s_.size () - (s_.size () > 0)) <= data_.size (), bad_index ());
        }

        // Accessors
        BOOST_UBLAS_INLINE
        size_type start () const {
            return s_.start ();
        }
        BOOST_UBLAS_INLINE
        difference_type stride () const {
            return s_.stride ();
        }
        BOOST_UBLAS_INLINE
        size_type size () const {
            return s_.size ();
        }

        // Storage accessors
        BOOST_UBLAS_INLINE
        const vector_closure_type &data () const {
            return data_;
        }
        BOOST_UBLAS_INLINE
        vector_closure_type &data () {
            return data_;
        }

        // Element access
#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
        BOOST_UBLAS_INLINE
        const_reference operator () (size_type i) const {
            return data_ (s_ (i));
        }
        BOOST_UBLAS_INLINE
        reference operator () (size_type i) {
            return data_ (s_ (i));
        }

        BOOST_UBLAS_INLINE
        const_reference operator [] (size_type i) const {
            return (*this) (i);
        }
        BOOST_UBLAS_INLINE
        reference operator [] (size_type i) {
            return (*this) (i);
        }
#else
        BOOST_UBLAS_INLINE
        reference operator () (size_type i) const {
            return data_ (s_ (i));
        }

        BOOST_UBLAS_INLINE
        reference operator [] (size_type i) const {
            return (*this) (i);
        }
#endif

        // ISSUE can this be done in free project function?
        // Although a const function can create a non-const proxy to a non-const object
        // Critical is that vector_type and data_ (vector_closure_type) are const correct
        BOOST_UBLAS_INLINE
        vector_slice<vector_type> project (const range_type &r) const {
            return vector_slice<vector_type>  (data_, s_.compose (r.preprocess (data_.size ())), false);
        }
        BOOST_UBLAS_INLINE
        vector_slice<vector_type> project (const slice_type &s) const {
            return vector_slice<vector_type>  (data_, s_.compose (s.preprocess (data_.size ())), false);
        }

        // Assignment
        BOOST_UBLAS_INLINE
        vector_slice &operator = (const vector_slice &vs) {
            // ISSUE need a temporary, proxy can be overlaping alias
            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vs));
            return *this;
        }
        BOOST_UBLAS_INLINE
        vector_slice &assign_temporary (vector_slice &vs) {
            // assign elements, proxied container remains the same
            vector_assign<scalar_assign> (*this, vs);
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_slice &operator = (const vector_expression<AE> &ae) {
            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_slice &assign (const vector_expression<AE> &ae) {
            vector_assign<scalar_assign> (*this, ae);
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_slice &operator += (const vector_expression<AE> &ae) {
            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_slice &plus_assign (const vector_expression<AE> &ae) {
            vector_assign<scalar_plus_assign> (*this, ae);
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_slice &operator -= (const vector_expression<AE> &ae) {
            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_slice &minus_assign (const vector_expression<AE> &ae) {
            vector_assign<scalar_minus_assign> (*this, ae);
            return *this;
        }
        template<class AT>
        BOOST_UBLAS_INLINE
        vector_slice &operator *= (const AT &at) {
            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
            return *this;
        }
        template<class AT>
        BOOST_UBLAS_INLINE
        vector_slice &operator /= (const AT &at) {
            vector_assign_scalar<scalar_divides_assign> (*this, at);
            return *this;
        }

        // Closure comparison
        BOOST_UBLAS_INLINE
        bool same_closure (const vector_slice &vr) const {
            return (*this).data_.same_closure (vr.data_);
        }

        // Comparison
        BOOST_UBLAS_INLINE
        bool operator == (const vector_slice &vs) const {
            return (*this).data_ == vs.data_ && s_ == vs.s_;
        }

        // Swapping
        BOOST_UBLAS_INLINE
        void swap (vector_slice vs) {
            if (this != &vs) {
                BOOST_UBLAS_CHECK (size () == vs.size (), bad_size ());
                // Sparse ranges may be nonconformant now.
                // std::swap_ranges (begin (), end (), vs.begin ());
                vector_swap<scalar_swap> (*this, vs);
            }
        }
        BOOST_UBLAS_INLINE
        friend void swap (vector_slice vs1, vector_slice vs2) {
            vs1.swap (vs2);
        }

        // Iterator types
    private:
        // Use slice as an index - FIXME this fails for packed assignment
        typedef typename slice_type::const_iterator const_subiterator_type;
        typedef typename slice_type::const_iterator subiterator_type;

    public:
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
        typedef indexed_iterator<vector_slice<vector_type>,
                                 typename vector_type::iterator::iterator_category> iterator;
        typedef indexed_const_iterator<vector_slice<vector_type>,
                                       typename vector_type::const_iterator::iterator_category> const_iterator;
#else
        class const_iterator;
        class iterator;
#endif

        // Element lookup
        BOOST_UBLAS_INLINE
        const_iterator find (size_type i) const {
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
            return const_iterator (*this, i);
#else
            return const_iterator (*this, s_.begin () + i);
#endif
        }
        BOOST_UBLAS_INLINE
        iterator find (size_type i) {
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
            return iterator (*this, i);
#else
            return iterator (*this, s_.begin () + i);
#endif
        }

#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
        class const_iterator:
            public container_const_reference<vector_slice>,
            public iterator_base_traits<typename V::const_iterator::iterator_category>::template
                        iterator_base<const_iterator, value_type>::type {
        public:
            typedef typename V::const_iterator::difference_type difference_type;
            typedef typename V::const_iterator::value_type value_type;
            typedef typename V::const_reference reference;    //FIXME due to indexing access
            typedef typename V::const_iterator::pointer pointer;

            // Construction and destruction
            BOOST_UBLAS_INLINE
            const_iterator ():
                container_const_reference<self_type> (), it_ () {}
            BOOST_UBLAS_INLINE
            const_iterator (const self_type &vs, const const_subiterator_type &it):
                container_const_reference<self_type> (vs), it_ (it) {}
            BOOST_UBLAS_INLINE
            const_iterator (const iterator &it):
                container_const_reference<self_type> (it ()), it_ (it.it_) {}

            // Arithmetic
            BOOST_UBLAS_INLINE
            const_iterator &operator ++ () {
                ++ it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator -- () {
                -- it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator += (difference_type n) {
                it_ += n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator -= (difference_type n) {
                it_ -= n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            difference_type operator - (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ - it.it_;
            }

            // Dereference
            BOOST_UBLAS_INLINE
            const_reference operator * () const {
                // FIXME replace find with at_element
                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
                return (*this) ().data_ (*it_);
            }

            // Index
            BOOST_UBLAS_INLINE
            size_type index () const {
                return it_.index ();
            }

            // Assignment
            BOOST_UBLAS_INLINE
            const_iterator &operator = (const const_iterator &it) {
                container_const_reference<self_type>::assign (&it ());
                it_ = it.it_;
                return *this;
            }

            // Comparison
            BOOST_UBLAS_INLINE
            bool operator == (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ == it.it_;
            }
            BOOST_UBLAS_INLINE
            bool operator < (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ < it.it_;
            }

        private:
            const_subiterator_type it_;
        };
#endif

        BOOST_UBLAS_INLINE
        const_iterator begin () const {
            return find (0);
        }
        BOOST_UBLAS_INLINE
        const_iterator end () const {
            return find (size ());
        }

#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
        class iterator:
            public container_reference<vector_slice>,
            public iterator_base_traits<typename V::iterator::iterator_category>::template
                        iterator_base<iterator, value_type>::type {
        public:
            typedef typename V::iterator::difference_type difference_type;
            typedef typename V::iterator::value_type value_type;
            typedef typename V::reference reference;    //FIXME due to indexing access
            typedef typename V::iterator::pointer pointer;

            // Construction and destruction
            BOOST_UBLAS_INLINE
            iterator ():
                container_reference<self_type> (), it_ () {}
            BOOST_UBLAS_INLINE
            iterator (self_type &vs, const subiterator_type &it):
                container_reference<self_type> (vs), it_ (it) {}

            // Arithmetic
            BOOST_UBLAS_INLINE
            iterator &operator ++ () {
                ++ it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            iterator &operator -- () {
                -- it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            iterator &operator += (difference_type n) {
                it_ += n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            iterator &operator -= (difference_type n) {
                it_ -= n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            difference_type operator - (const iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ - it.it_;
            }

            // Dereference
            BOOST_UBLAS_INLINE
            reference operator * () const {
                // FIXME replace find with at_element
                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
                return (*this) ().data_ (*it_);
            }

            // Index
            BOOST_UBLAS_INLINE
            size_type index () const {
                return it_.index ();
            }

            // Assignment
            BOOST_UBLAS_INLINE
            iterator &operator = (const iterator &it) {
                container_reference<self_type>::assign (&it ());
                it_ = it.it_;
                return *this;
            }

            // Comparison
            BOOST_UBLAS_INLINE
            bool operator == (const iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ == it.it_;
            }
            BOOST_UBLAS_INLINE
            bool operator < (const iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ < it.it_;
            }

        private:
            subiterator_type it_;

            friend class const_iterator;
        };
#endif

        BOOST_UBLAS_INLINE
        iterator begin () {
            return find (0);
        }
        BOOST_UBLAS_INLINE
        iterator end () {
            return find (size ());
        }

        // Reverse iterator
        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
        typedef reverse_iterator_base<iterator> reverse_iterator;

        BOOST_UBLAS_INLINE
        const_reverse_iterator rbegin () const {
            return const_reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator rend () const {
            return const_reverse_iterator (begin ());
        }
        BOOST_UBLAS_INLINE
        reverse_iterator rbegin () {
            return reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        reverse_iterator rend () {
            return reverse_iterator (begin ());
        }

    private:
        vector_closure_type data_;
        slice_type s_;
    };

    // Simple Projections
    template<class V>
    BOOST_UBLAS_INLINE
    vector_slice<V> subslice (V &data, typename V::size_type start, typename V::difference_type stride, typename V::size_type size) {
        typedef basic_slice<typename V::size_type, typename V::difference_type> slice_type;
        return vector_slice<V> (data, slice_type (start, stride, size));
    }
    template<class V>
    BOOST_UBLAS_INLINE
    vector_slice<const V> subslice (const V &data, typename V::size_type start, typename V::difference_type stride, typename V::size_type size)  {
        typedef basic_slice<typename V::size_type, typename V::difference_type> slice_type;
        return vector_slice<const V> (data, slice_type (start, stride, size));
    }

    // Generic Projections
    template<class V>
    BOOST_UBLAS_INLINE
    vector_slice<V> project (V &data, const typename vector_slice<V>::slice_type &s) {
        return vector_slice<V> (data, s);
    }
    template<class V>
    BOOST_UBLAS_INLINE
    const vector_slice<const V> project (const V &data, const typename vector_slice<V>::slice_type &s) {
        // ISSUE was: return vector_slice<V> (const_cast<V &> (data), s);
        return vector_slice<const V> (data, s);
    }
    template<class V>
    BOOST_UBLAS_INLINE
    vector_slice<V> project (vector_slice<V> &data, const typename vector_slice<V>::slice_type &s) {
        return data.project (s);
    }
    template<class V>
    BOOST_UBLAS_INLINE
    const vector_slice<V> project (const vector_slice<V> &data, const typename vector_slice<V>::slice_type &s) {
        return data.project (s);
    }
    // ISSUE in the following two functions it would be logical to use vector_slice<V>::range_type but this confuses VC7.1 and 8.0
    template<class V>
    BOOST_UBLAS_INLINE
    vector_slice<V> project (vector_slice<V> &data, const typename vector_range<V>::range_type &r) {
        return data.project (r);
    }
    template<class V>
    BOOST_UBLAS_INLINE
    const vector_slice<V> project (const vector_slice<V> &data, const typename vector_range<V>::range_type &r) {
        return data.project (r);
    }

    // Specialization of temporary_traits
    template <class V>
    struct vector_temporary_traits< vector_slice<V> >
    : vector_temporary_traits< V > {} ;

    // Vector based indirection class
    // Contributed by Toon Knapen.
    // Extended and optimized by Kresimir Fresl.
    template<class V, class IA>
    class vector_indirect:
        public vector_expression<vector_indirect<V, IA> > {

        typedef vector_indirect<V, IA> self_type;
    public:
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
        using vector_expression<self_type>::operator ();
#endif
        typedef const V const_vector_type;
        typedef V vector_type;
        typedef const IA const_indirect_array_type;
        typedef IA indirect_array_type;
        typedef typename V::size_type size_type;
        typedef typename V::difference_type difference_type;
        typedef typename V::value_type value_type;
        typedef typename V::const_reference const_reference;
        typedef typename boost::mpl::if_<boost::is_const<V>,
                                          typename V::const_reference,
                                          typename V::reference>::type reference;
        typedef typename boost::mpl::if_<boost::is_const<V>,
                                          typename V::const_closure_type,
                                          typename V::closure_type>::type vector_closure_type;
        typedef basic_range<size_type, difference_type> range_type;
        typedef basic_slice<size_type, difference_type> slice_type;
        typedef const self_type const_closure_type;
        typedef self_type closure_type;
        typedef typename storage_restrict_traits<typename V::storage_category,
                                                 dense_proxy_tag>::storage_category storage_category;

        // Construction and destruction
        BOOST_UBLAS_INLINE
        vector_indirect (vector_type &data, size_type size):
            data_ (data), ia_ (size) {}
        BOOST_UBLAS_INLINE
        vector_indirect (vector_type &data, const indirect_array_type &ia):
            data_ (data), ia_ (ia.preprocess (data.size ())) {}
        BOOST_UBLAS_INLINE
        vector_indirect (const vector_closure_type &data, const indirect_array_type &ia, int):
            data_ (data), ia_ (ia.preprocess (data.size ())) {}

        // Accessors
        BOOST_UBLAS_INLINE
        size_type size () const {
            return ia_.size ();
        }
        BOOST_UBLAS_INLINE
        const_indirect_array_type &indirect () const {
            return ia_;
        }
        BOOST_UBLAS_INLINE
        indirect_array_type &indirect () {
            return ia_;
        }

        // Storage accessors
        BOOST_UBLAS_INLINE
        const vector_closure_type &data () const {
            return data_;
        }
        BOOST_UBLAS_INLINE
        vector_closure_type &data () {
            return data_;
        }

        // Element access
#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
        BOOST_UBLAS_INLINE
        const_reference operator () (size_type i) const {
            return data_ (ia_ (i));
        }
        BOOST_UBLAS_INLINE
        reference operator () (size_type i) {
            return data_ (ia_ (i));
        }

        BOOST_UBLAS_INLINE
        const_reference operator [] (size_type i) const {
            return (*this) (i);
        }
        BOOST_UBLAS_INLINE
        reference operator [] (size_type i) {
            return (*this) (i);
        }
#else
        BOOST_UBLAS_INLINE
        reference operator () (size_type i) const {
            return data_ (ia_ (i));
        }

        BOOST_UBLAS_INLINE
        reference operator [] (size_type i) const {
            return (*this) (i);
        }
#endif

        // ISSUE can this be done in free project function?
        // Although a const function can create a non-const proxy to a non-const object
        // Critical is that vector_type and data_ (vector_closure_type) are const correct
        BOOST_UBLAS_INLINE
        vector_indirect<vector_type, indirect_array_type> project (const range_type &r) const {
            return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (r.preprocess (data_.size ())), 0);
        }
        BOOST_UBLAS_INLINE
        vector_indirect<vector_type, indirect_array_type> project (const slice_type &s) const {
            return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (s.preprocess (data_.size ())), 0);
        }
        BOOST_UBLAS_INLINE
        vector_indirect<vector_type, indirect_array_type> project (const indirect_array_type &ia) const {
            return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (ia.preprocess (data_.size ())), 0);
        }

        // Assignment
        BOOST_UBLAS_INLINE
        vector_indirect &operator = (const vector_indirect &vi) {
            // ISSUE need a temporary, proxy can be overlaping alias
            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vi));
            return *this;
        }
        BOOST_UBLAS_INLINE
        vector_indirect &assign_temporary (vector_indirect &vi) {
            // assign elements, proxied container remains the same
            vector_assign<scalar_assign> (*this, vi);
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_indirect &operator = (const vector_expression<AE> &ae) {
            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_indirect &assign (const vector_expression<AE> &ae) {
            vector_assign<scalar_assign> (*this, ae);
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_indirect &operator += (const vector_expression<AE> &ae) {
            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_indirect &plus_assign (const vector_expression<AE> &ae) {
            vector_assign<scalar_plus_assign> (*this, ae);
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_indirect &operator -= (const vector_expression<AE> &ae) {
            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
            return *this;
        }
        template<class AE>
        BOOST_UBLAS_INLINE
        vector_indirect &minus_assign (const vector_expression<AE> &ae) {
            vector_assign<scalar_minus_assign> (*this, ae);
            return *this;
        }
        template<class AT>
        BOOST_UBLAS_INLINE
        vector_indirect &operator *= (const AT &at) {
            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
            return *this;
        }
        template<class AT>
        BOOST_UBLAS_INLINE
        vector_indirect &operator /= (const AT &at) {
            vector_assign_scalar<scalar_divides_assign> (*this, at);
            return *this;
        }

        // Closure comparison
        BOOST_UBLAS_INLINE
        bool same_closure (const vector_indirect &vr) const {
return true;
        }

        // Comparison
        BOOST_UBLAS_INLINE
        bool operator == (const vector_indirect &vi) const {
            return (*this).data_ == vi.data_ && ia_ == vi.ia_;
        }

        // Swapping
        BOOST_UBLAS_INLINE
        void swap (vector_indirect vi) {
            if (this != &vi) {
                BOOST_UBLAS_CHECK (size () == vi.size (), bad_size ());
                // Sparse ranges may be nonconformant now.
                // std::swap_ranges (begin (), end (), vi.begin ());
                vector_swap<scalar_swap> (*this, vi);
            }
        }
        BOOST_UBLAS_INLINE
        friend void swap (vector_indirect vi1, vector_indirect vi2) {
            vi1.swap (vi2);
        }

        // Iterator types
    private:
        // Use indirect array as an index - FIXME this fails for packed assignment
        typedef typename IA::const_iterator const_subiterator_type;
        typedef typename IA::const_iterator subiterator_type;

    public:
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
        typedef indexed_iterator<vector_indirect<vector_type, indirect_array_type>,
                                 typename vector_type::iterator::iterator_category> iterator;
        typedef indexed_const_iterator<vector_indirect<vector_type, indirect_array_type>,
                                       typename vector_type::const_iterator::iterator_category> const_iterator;
#else
        class const_iterator;
        class iterator;
#endif
        // Element lookup
        BOOST_UBLAS_INLINE
        const_iterator find (size_type i) const {
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
            return const_iterator (*this, i);
#else
            return const_iterator (*this, ia_.begin () + i);
#endif
        }
        BOOST_UBLAS_INLINE
        iterator find (size_type i) {
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
            return iterator (*this, i);
#else
            return iterator (*this, ia_.begin () + i);
#endif
        }

        // Iterators simply are indices.

#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
        class const_iterator:
            public container_const_reference<vector_indirect>,
            public iterator_base_traits<typename V::const_iterator::iterator_category>::template
                        iterator_base<const_iterator, value_type>::type {
        public:
            typedef typename V::const_iterator::difference_type difference_type;
            typedef typename V::const_iterator::value_type value_type;
            typedef typename V::const_reference reference;    //FIXME due to indexing access
            typedef typename V::const_iterator::pointer pointer;

            // Construction and destruction
            BOOST_UBLAS_INLINE
            const_iterator ():
                container_const_reference<self_type> (), it_ () {}
            BOOST_UBLAS_INLINE
            const_iterator (const self_type &vi, const const_subiterator_type &it):
                container_const_reference<self_type> (vi), it_ (it) {}
            BOOST_UBLAS_INLINE
            const_iterator (const iterator &it):
                container_const_reference<self_type> (it ()), it_ (it.it_) {}

            // Arithmetic
            BOOST_UBLAS_INLINE
            const_iterator &operator ++ () {
                ++ it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator -- () {
                -- it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator += (difference_type n) {
                it_ += n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator -= (difference_type n) {
                it_ -= n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            difference_type operator - (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ - it.it_;
            }

            // Dereference
            BOOST_UBLAS_INLINE
            const_reference operator * () const {
                // FIXME replace find with at_element
                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
                return (*this) ().data_ (*it_);
            }

            // Index
            BOOST_UBLAS_INLINE
            size_type index () const {
                return it_.index ();
            }

            // Assignment
            BOOST_UBLAS_INLINE
            const_iterator &operator = (const const_iterator &it) {
                container_const_reference<self_type>::assign (&it ());
                it_ = it.it_;
                return *this;
            }

            // Comparison
            BOOST_UBLAS_INLINE
            bool operator == (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ == it.it_;
            }
            BOOST_UBLAS_INLINE
            bool operator < (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ < it.it_;
            }

        private:
            const_subiterator_type it_;
        };
#endif

        BOOST_UBLAS_INLINE
        const_iterator begin () const {
            return find (0);
        }
        BOOST_UBLAS_INLINE
        const_iterator end () const {
            return find (size ());
        }

#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
        class iterator:
            public container_reference<vector_indirect>,
            public iterator_base_traits<typename V::iterator::iterator_category>::template
                        iterator_base<iterator, value_type>::type {
        public:
            typedef typename V::iterator::difference_type difference_type;
            typedef typename V::iterator::value_type value_type;
            typedef typename V::reference reference;    //FIXME due to indexing access
            typedef typename V::iterator::pointer pointer;

            // Construction and destruction
            BOOST_UBLAS_INLINE
            iterator ():
                container_reference<self_type> (), it_ () {}
            BOOST_UBLAS_INLINE
            iterator (self_type &vi, const subiterator_type &it):
                container_reference<self_type> (vi), it_ (it) {}

            // Arithmetic
            BOOST_UBLAS_INLINE
            iterator &operator ++ () {
                ++ it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            iterator &operator -- () {
                -- it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            iterator &operator += (difference_type n) {
                it_ += n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            iterator &operator -= (difference_type n) {
                it_ -= n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            difference_type operator - (const iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ - it.it_;
            }

            // Dereference
            BOOST_UBLAS_INLINE
            reference operator * () const {
                // FIXME replace find with at_element
                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
                return (*this) ().data_ (*it_);
            }

            // Index
            BOOST_UBLAS_INLINE
            size_type index () const {
                return it_.index ();
            }

            // Assignment
            BOOST_UBLAS_INLINE
            iterator &operator = (const iterator &it) {
                container_reference<self_type>::assign (&it ());
                it_ = it.it_;
                return *this;
            }

            // Comparison
            BOOST_UBLAS_INLINE
            bool operator == (const iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ == it.it_;
            }
            BOOST_UBLAS_INLINE
            bool operator < (const iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
                return it_ < it.it_;
            }

        private:
            subiterator_type it_;

            friend class const_iterator;
        };
#endif

        BOOST_UBLAS_INLINE
        iterator begin () {
            return find (0);
        }
        BOOST_UBLAS_INLINE
        iterator end () {
            return find (size ());
        }

        // Reverse iterator
        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
        typedef reverse_iterator_base<iterator> reverse_iterator;

        BOOST_UBLAS_INLINE
        const_reverse_iterator rbegin () const {
            return const_reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator rend () const {
            return const_reverse_iterator (begin ());
        }
        BOOST_UBLAS_INLINE
        reverse_iterator rbegin () {
            return reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        reverse_iterator rend () {
            return reverse_iterator (begin ());
        }

    private:
        vector_closure_type data_;
        indirect_array_type ia_;
    };

    // Projections
    template<class V, class A>
    BOOST_UBLAS_INLINE
    vector_indirect<V, indirect_array<A> > project (V &data, const indirect_array<A> &ia) {
        return vector_indirect<V, indirect_array<A> > (data, ia);
    }
    template<class V, class A>
    BOOST_UBLAS_INLINE
    const vector_indirect<const V, indirect_array<A> > project (const V &data, const indirect_array<A> &ia) {
        // ISSUE was: return vector_indirect<V, indirect_array<A> > (const_cast<V &> (data), ia)
        return vector_indirect<const V, indirect_array<A> > (data, ia);
    }
    template<class V, class IA>
    BOOST_UBLAS_INLINE
    vector_indirect<V, IA> project (vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::range_type &r) {
        return data.project (r);
    }
    template<class V, class IA>
    BOOST_UBLAS_INLINE
    const vector_indirect<V, IA> project (const vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::range_type &r) {
        return data.project (r);
    }
    template<class V, class IA>
    BOOST_UBLAS_INLINE
    vector_indirect<V, IA> project (vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::slice_type &s) {
        return data.project (s);
    }
    template<class V, class IA>
    BOOST_UBLAS_INLINE
    const vector_indirect<V, IA> project (const vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::slice_type &s) {
        return data.project (s);
    }
    template<class V, class A>
    BOOST_UBLAS_INLINE
    vector_indirect<V, indirect_array<A> > project (vector_indirect<V, indirect_array<A> > &data, const indirect_array<A> &ia) {
        return data.project (ia);
    }
    template<class V, class A>
    BOOST_UBLAS_INLINE
    const vector_indirect<V, indirect_array<A> > project (const vector_indirect<V, indirect_array<A> > &data, const indirect_array<A> &ia) {
        return data.project (ia);
    }

    // Specialization of temporary_traits
    template <class V>
    struct vector_temporary_traits< vector_indirect<V> >
    : vector_temporary_traits< V > {} ;

}}}

#endif